Handbuch zur Problembehandlung für Spring JMS

In diesem Artikel wird beschrieben, wie Bekannte Probleme und häufige Fehler bei verwendung von Spring JMS behoben werden. Der Artikel beantwortet auch einige häufig gestellte Fragen zu spring-cloud-azure-starter-servicebus-jms.

Konnektivitätsprobleme

Der MessageProducer wurde aufgrund eines nicht behebbaren Fehlers geschlossen.

Problembeschreibung

Wenn sie JmsTemplate zum Senden von Nachrichten verwenden, wird JmsTemplate während eines Leerlaufintervalls zwischen 10 und 15 Minuten nicht verfügbar. Das Senden von Nachrichten in diesem Intervall kann die in der folgenden Beispielausgabe gezeigten Ausnahmen abrufen:

2022-11-06 11:12:05.762  INFO 25944 --- [   scheduling-1] c.e.demo.ServiceBusJMSMessageProducer    : Sending message: 2022-11-06T11:12:05.762072 message 1
2022-11-06 11:12:05.772 ERROR 25944 --- [   scheduling-1] o.s.s.s.TaskUtils$LoggingErrorHandler    : Unexpected error occurred in scheduled task

org.springframework.jms.IllegalStateException: The MessageProducer was closed due to an unrecoverable error.; nested exception is javax.jms.IllegalStateException: The MessageProducer was closed due to an unrecoverable error.
    at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:274) ~[spring-jms-5.3.23.jar:5.3.23]
  ...
Caused by: org.apache.qpid.jms.provider.ProviderException: The link 'G0:36906660:qpid-jms:sender:azure:5caf3ef4-9602-413c-964d-cf1292d6e1f5:1:1:1:t4' is force detached. Code: publisher(link376). Details: AmqpMessagePublisher.IdleTimerExpired: Idle timeout: 00:10:00. [condition = amqp:link:detach-forced]
    at org.apache.qpid.jms.provider.amqp.AmqpSupport.convertToNonFatalException(AmqpSupport.java:181) ~[qpid-jms-client-0.53.0.jar:na]
  ...

Ursachenanalyse

Die Ausnahmen treten für Azure Service Bus auf, wenn die AMQP-Verbindung und der Link aktiv sind, aber keine Anrufe ( z. B. Senden oder Empfangen von Anrufen ) über den Link für 10 Minuten erfolgen. In diesem Fall wird der Link geschlossen. Und wenn alle Verknüpfungen in der Verbindung geschlossen wurden, weil keine Aktivität (im Leerlauf) vorhanden war und keine neue Verknüpfung in 5 Minuten erstellt wurde, wird die Verbindung geschlossen.

Für den Service Bus JMS-Starter wird standardmäßig die CachingConnectionFactory verwendet, die die Sitzung, den Producer und den Consumer zwischenspeichert. Wenn die JmsProducer länger als 10 Minuten, aber weniger als 15 Minuten inaktiv ist, ist der Link, den der zwischengespeicherte Produzent belegt, geschlossen worden. Nachrichten können während dieses Intervalls nicht gesendet werden. Nach einem weiteren Leerlauf von 5 Minuten wird dann die gesamte Verbindung geschlossen. Daher bewirkt jeder Sendevorgang nach dem 15-Minuten-Leerlaufintervall, dass der CachingConnectionFactory eine neue Verbindung zum Senden erstellt. Der Sendevorgang ist nach 15 Minuten verfügbar.

Problemumgehung

Derzeit bietet der Starter einen Workaround für das Link-Detach-Problem, indem JmsPoolConnectionFactory angewendet wird, das Connection, Session und MessageProducer poolt und den Lebenszyklus der gepoolten Instanzen verwaltet. Dieser Workaround kann sicherstellen, dass ein Produzent entfernt wird, nachdem er nicht mehr verfügbar war, sodass alle Sendevorgänge über aktive Produzenten erfolgen.

Um diese Problemumgehung zu verwenden, fügen Sie die folgende Konfiguration hinzu:

spring:
  jms:
    servicebus:
      pool:
        enabled: true
        max-connections: ${your-expected-max-connection-value}

Verwendung von spring.jms.servicebus.idle-timeout

Die Eigenschaften für das Leerlauf-Timeout einer AMQP-Verbindung werden mit diesen Einstellungen konfiguriert. Die AMQP-Spezifikation enthält die folgende Beschreibung:

Verbindungen unterliegen einer Leerlauf-Timeout-Grenze. Das Timeout wird von einem lokalen Peer ausgelöst, wenn keine Frames empfangen werden, nachdem ein Schwellenwert überschritten wurde. Der Leerlauftimeout wird in Millisekunden gemessen und beginnt ab dem Zeitpunkt, zu dem der letzte Frame empfangen wird. Wenn der Schwellenwert überschritten wird, SOLLTE ein Peer versuchen, die Verbindung geordnet mithilfe eines Close-Frames zu schließen, das mit einer Fehlermeldung erklärt, warum. Wenn der Remote-Peer darauf nicht innerhalb einer bestimmten Frist ordnungsgemäß reagiert, DARF der Peer den TCP-Socket schließen.

Bei einem JMS-Client steuern Sie beim Konfigurieren dieser Eigenschaft auf der Serverseite, wie lange der Server einen leeren Frame sendet, um eine Verbindung lebendig zu halten, wenn keine Nachrichten übermittelt werden. Diese Eigenschaft steuert das Verhalten des Remote-Peers, und jeder Peer kann einen eigenen, isolierten Wert aufweisen.

JmsTemplate-Probleme

Geplante Nachrichten

Azure Service Bus unterstützt verzögerte Nachrichtenverarbeitung. Weitere Informationen finden Sie im Abschnitt Geplanten Nachrichten Abschnitt Nachrichtensequenzierung und Zeitstempel. Legen Sie für JMS zum Planen einer Nachricht die eigenschaft ScheduledEnqueueTimeUtc mithilfe des Nachrichtenanmerkungsheaders x-opt-scheduled-enqueue-timefest.

JmsListener-Probleme

Zu viele Anforderungen werden an Service Bus gesendet, obwohl keine Nachrichten auf dem Server vorhanden sind.

Problembeschreibung

Bei Verwendung der @JmsListener-API können Sie in einigen Fällen im Azure-Portal sehen, dass es fortlaufende Werte für eingehende Anforderungen gibt, die an ihre Warteschlange oder ihre Themen gesendet werden, auch wenn keine Nachrichten auf dem Server empfangen werden.

Ursachenanalyse

@JmsListener ist ein Polling-Listener, der für wiederholte Polling-Versuche ausgelegt ist.

Der Listener befindet sich in einer laufenden Abfrageschleife. Bei jedem Durchlauf wird die JMS-MessageConsumer.receive()-Methode aufgerufen, um den lokalen Nachrichten-Consumer auf zu empfangende Nachrichten abzufragen. Standardmäßig sendet der lokale Consumer für jeden Abrufvorgang Pull-Anforderungen an den Nachrichtenbroker, um Nachrichten anzufordern und dann für einen bestimmten Zeitraum zu blockieren. Der konkrete Abrufprozess wird durch mehrere Eigenschaften bestimmt, einschließlich receiveTimeout, prefetchSize und receiveLocalOnly oder receiveNoWaitLocalOnly. Die receiveNoWaitLocalOnly-Methode wird nur verwendet, wenn Sie receiveTimeout auf einen negativen Wert festlegen.

Wenn dieses Problem mit Ihrer Anwendung auftritt, überprüfen Sie die folgenden Konfigurationseinstellungen:

  • Ermitteln Sie, ob Ihre Prefetch-Richtlinie auf 0 gesetzt ist, was auch die Standardeinstellung ist. 0-Prefetch bezeichnet einen Pull-Consumer, der bei jeder Abfrage Pull-Anfragen an den Service Bus sendet.

  • Wenn Sie einen Prefetch-Wert ungleich null konfiguriert haben, prüfen Sie, ob Ihre Eigenschaft receiveLocalOnly oder receiveNoWaitLocalOnly auf false festgelegt ist, was die Standardoption ist. Ein false-Wert hier führt weiterhin dazu, Pull-Anfragen an den Server zu senden, weil dabei nicht nur der lokale Consumer abgefragt wird.

  • Die receiveTimeout-Konfiguration bestimmt, wie lange bei jeder Abrufanforderung blockiert wird, und kann somit beeinflussen, wie häufig Abrufanforderungen an den Server gesendet werden. Der Standardwert ist 1 Sekunde.

Eine vollständige Analyse finden Sie in der Diskussion zu dem GitHub-Issue.

Lösungen

In den folgenden Abschnitten werden zwei Lösungen für den Umgang mit diesem Problem beschrieben.

Lösung 1. Änderung nur für Push-Consumer und lokale Prüfung

Wenn der Modus auf push geändert wird, wird der Consumer zu einem Consumer für asynchrone Benachrichtigungen, der keine Nachrichten vom Broker abruft, sondern eine Zielmenge an Link-Credit aufrechterhält. Die Menge wird durch eine Prefetch-Eigenschaft bestimmt. Wenn der ServiceBus (Absender) Nachrichten pusht, verringert sich die Linkgutschrift des Absenders und wenn die Linkgutschrift des Absenders unter einen Schwellenwert fällt, sendet der Kunde (Empfänger) eine Anforderung an den Server, um die Linkguthaben des Absenders wieder auf den gewünschten Zielbetrag zu erhöhen.

Um diese Lösung zu erreichen, fügen Sie die folgende Konfiguration hinzu:

Konfigurieren Sie zunächst die prefetch Zahl als ungleich Null, wodurch der Consumer als nicht pull konfiguriert wird. In der folgenden Tabelle sind mehrere Prefetch-Eigenschaften aufgeführt, von denen jede verschiedene ServiceBus-Entitäten steuert. Legen Sie die Eigenschaften fest, die für Ihren Fall gelten.

Eigentum Beschreibung
spring.jms.servicebus.prefetch.all Der Fallbackwert für die Option "Prefetch" in diesem Service Bus-Namespace
spring.jms.servicebus.prefetch.queue-prefetch Die Prefetch-Nummer für die Warteschlange.
spring.jms.servicebus.prefetch.queue-browser-prefetch Die Prefetch-Nummer für den Warteschlangenbrowser.
spring.jms.servicebus.prefetch.topic-prefetch Die Prefetch-Nummer für das Thema.
spring.jms.servicebus.prefetch.durable-topic-prefetch Die Prefetch-Nummer für das dauerhafte Thema.

Konfigurieren Sie zweitens die non-local-check, indem Sie eine Konfigurationsklasse für den Factory customizer hinzufügen, wie im folgenden Beispiel gezeigt:

@Configuration(proxyBeanMethods = false)
public class CustomJmsConfiguration {

    @Bean
    ServiceBusJmsConnectionFactoryCustomizer customizer() {
        return factory -> {
            factory.setReceiveLocalOnly(true);
            // Configure the below ReceiveNoWaitLocalOnly instead if you have specified the property 
            // spring.jms.listener.receive-timeout with negative value. Otherwise, configure the above `ReceiveLocalOnly`.
            //factory.setReceiveNoWaitLocalOnly(true);
        };
    }
}

Der Prefetch-Wert kann sich darauf auswirken, wie schnell Nachrichten an den lokalen Puffer des Verbrauchers verteilt werden. Sie sollten den Wert entsprechend Ihrer Verbrauchsleistung und Ihrem Nachrichtenvolumen anpassen. Ein geeigneter Wert kann den Verarbeitungsprozess beschleunigen, während ein zu großer Wert dazu führen kann, dass die lokal gepufferten Nachrichten veraltet und erneut verteilt werden. Bei geringem Nachrichtenaufkommen, wenn die Verarbeitung jeder Nachricht lange dauert, setzen Sie den Prefetch-Wert auf 1 fest. Dieser Wert stellt sicher, dass ein Verbraucher jeweils nur eine Nachricht verarbeitet.

Lösung 2. Erhöhen Sie das Empfangs-Timeout, um die Abruffrequenz zu verringern.

Die Eigenschaft für das Empfangs-Timeout legt fest, wie lange der Consumer blockiert, um auf ein Pull-Ergebnis zu warten. Wenn Sie also das Timeout erweitern, können Sie die Pullfrequenz verringern und dann die Anzahl der Pullanforderungen verringern, wenn Sie den Pullmodus auswählen. In Ausnahmefällen können Sie die Strategie so festlegen, dass unbegrenzt gewartet wird, bis eine Nachricht eingeht. Das bedeutet, dass der Consumer erst dann die nächste Nachricht abruft, nachdem er eine Nachricht verarbeitet hat. In diesem Fall wird das Warten blockiert, wenn keine Nachrichten auf dem Server vorhanden sind.

Um diese Lösung zu erreichen, konfigurieren Sie die spring.jms.listener.receive-timeout-Eigenschaft. Diese Eigenschaft ist vom Typ java.time.Duration und hat einen Standardwert von 1 Sekunde. In der folgenden Liste werden die Auswirkungen verschiedener Werte erläutert:

  • Das Festlegen des Empfangstimeouts auf 0 bedeutet, dass die Pullblöcke unbegrenzt bleiben, bis eine Nachricht verteilt wird.
  • Das Festlegen des Empfangs-Timeouts auf einen positiven Wert bedeutet, dass der Pull-Vorgang höchstens für die Timeout-Dauer blockiert.
  • Das Festlegen des Empfangstimeouts auf einen negativen Wert bedeutet, dass es sich bei dem Pull um einen Empfang ohne Wartezeit handelt, d. h. es wird sofort eine Nachricht zurückgegeben, oder null, wenn keine Nachrichten verfügbar sind.

Anmerkung

Ein hoher Timeoutwert kann einige Nebenwirkungen verursachen. Beispielsweise verlängert ein Hoher Timeoutwert auch die Zeit, zu der sich der Hauptthread in einem Blockstatus befindet. Dieser Status bedeutet, dass der Container weniger reaktionsfähig für stop() Anrufe ist und nur zwischen receive() Anrufen anhalten kann.

Außerdem kann der Container erst Anfragen senden, nachdem das receive-timeout Intervall verstrichen ist. Wenn das Intervall länger als 10 Minuten ist, schließt Service Bus den Link und verhindert, dass der Listener sendet oder empfängt. Weitere Informationen finden Sie im Abschnitt Link ist geschlossen Abschnitt AMQP-Fehler in Azure Service Bus. Standardmäßig verwendet der Listener eine CachingConnectionFactory.

Wenn Sie ein hohes Empfangs-Timeout benötigen, sollten Sie unbedingt die JmsPoolConnectionFactory verwenden.

Weitere Informationen zum Problem beim Schließen von Links und zur Verwendung von JmsPoolConnectionFactoryfinden Sie im Der MessageProducer wurde aufgrund eines nicht behebbaren Fehlers Abschnitt geschlossen.

Prefetch-Problem

Problembeschreibung

Eine ungeeignete Prefetch-Richtlinie kann die folgenden Probleme verursachen:

  • Dieselben Nachrichten werden wiederholt verarbeitet.
  • Nachrichten werden nach MaxDeliveryCountExceeded in die Dead-Letter-Warteschlange verschoben, selbst wenn sie ohne Fehler oder Ausnahmen verarbeitet werden.

Ursachenanalyse

Dieses Problem tritt in der Regel auf, wenn der prefetch Wert höher als die tatsächliche Verbrauchkapazität ist, mit dem Effekt, dass zu viele Nachrichten in den lokalen Puffer voreingestellt werden, der auf die Nutzung wartet. Die vorab abgerufenen Nachrichten werden jedoch seitens des Service Bus im Modus peek-lock als gesendet betrachtet. Jede verteilte Nachricht verfügt über eine max-delivery-count und lock-duration Attribute. peek-lock Im Empfangsmodus werden nachrichten, die im Prefetch-Puffer abgerufen werden, in den Puffer in einem gesperrten Zustand übernommen, wobei die Timeoutuhr für das Sperren tickt. Wenn der Prefetch-Puffer groß ist und die Verarbeitung so lange dauert, dass Nachrichtensperren ablaufen, während sich die Nachrichten noch im Prefetch-Puffer befinden, wird die Nachricht als aufgegeben behandelt und erneut zum Abruf aus der Warteschlange verfügbar gemacht.

Dieses Problem kann dazu führen, dass die Nachricht in den Prefetch-Puffer geladen und am Ende eingefügt wird. Wenn der Prefetchpuffer nicht verarbeitet wird, bevor die Nachricht abläuft, werden Nachrichten wiederholt im Voraus abgerufen, aber nie effektiv in einem nutzbaren Zustand (mit gültiger Sperre) zugestellt. Dann verarbeitet die Anwendung, wenn diese veralteten Kopien aus der Warteschlange genommen werden, immer wieder dieselbe Nachricht und kann deren Verarbeitung nicht abschließen. In einem anderen Fall sind wiederholte Nachrichten alle im Puffer abgelaufen, bevor sie verarbeitet wurden. In diesem Fall wird die Nachricht im Servicebus schließlich in die Warteschleife verschoben, nachdem die maximale Anzahl der Zustellungen überschritten wurde.

Weitere Informationen finden Sie im Warum ist Prefetch nicht die Standardoption? Abschnitt der Prefetch Azure Service Bus-Nachrichten.

Lösung

Achten Sie bei der Konfiguration des Prefetchs darauf, dass sie auf die Verarbeitungskapazität abgestimmt ist. Sie müssen die maximale Prefetch-Anzahl und die für die Warteschlange oder das Abonnement konfigurierte Sperrdauer so aufeinander abstimmen, dass das Sperrtimeout mindestens die kumulierte erwartete Nachrichtenverarbeitungszeit für die maximale Größe des Prefetchpuffers plus einer weiteren Nachricht überschreitet. Gleichzeitig sollte das Sperrtimeout nicht so lang sein, dass Nachrichten ihre maximale Lebensdauer überschreiten können, wenn sie versehentlich verworfen werden und daher zunächst ihre Sperre ablaufen muss, bevor sie erneut zugestellt werden.

Verwenden Sie eine der folgenden Eigenschaften, um das Prefetch-Attribut zu konfigurieren, das den Standardwert null hat:

Eigentum Beschreibung
spring.jms.servicebus.prefetch.all Der Fallbackwert für die Option "Prefetch" in diesem Service Bus-Namespace.
spring.jms.servicebus.prefetch.queue-prefetch Die Prefetch-Nummer für die Warteschlange.
spring.jms.servicebus.prefetch.queue-browser-prefetch Die Prefetch-Nummer für den Warteschlangenbrowser.
spring.jms.servicebus.prefetch.topic-prefetch Die Prefetch-Nummer für das Thema.
spring.jms.servicebus.prefetch.durable-topic-prefetch Die Prefetch-Nummer für das dauerhafte Thema.

Wie führt man eine AMQP-Disposition für Service Bus aus?

JMS unterstützt fünf AMQP-Dispositionstypen bei der Bestätigung von Nachrichten gegenüber dem Messaging-Broker. Die unterstützten Werte sind ACCEPTED, REJECTED, RELEASED, MODIFIED_FAILEDund MODIFIED_FAILED_UNDELIVERABLE. Weitere Informationen finden Sie in der AMQP-Dispositions- und ServiceBus-Vorgangszuordnung Abschnitt Verwenden von Java Message Service Service 1.1 mit azure Service Bus Standard und AMQP 1.0.

Führen Sie daher die folgenden Schritte aus, um eine Nachricht mithilfe von JmsListenermanuell abzuschließen, zu verlassen, zu verwerfen, zu verzögern oder freizugeben:

  1. Deaktivieren Sie Sitzungstransaktionen, und verwenden Sie den CLIENT-Ack-Modus.

    Um dies zu erreichen, deklarieren Sie entweder Ihre eigene JmsListenerContainerFactory-Bean und legen dann die Eigenschaften fest, oder bearbeiten das im starter definierte JmsListenerContainerFactory nach. Im folgenden Beispiel wird der Ansatz verwendet, ein weiteres Bean zu deklarieren:

    @Configuration(proxyBeanMethods = false)
    public class CustomJmsConfiguration {
    
        @Bean
        public JmsListenerContainerFactory<?> customQueueJmsListenerContainerFactory(
                DefaultJmsListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) {
            DefaultJmsListenerContainerFactory jmsListenerContainerFactory = new DefaultJmsListenerContainerFactory();
            configurer.configure(jmsListenerContainerFactory, connectionFactory);
            jmsListenerContainerFactory.setPubSubDomain(Boolean.FALSE);
            jmsListenerContainerFactory.setSessionTransacted(Boolean.FALSE);
            jmsListenerContainerFactory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
            return jmsListenerContainerFactory;
        }
    }
    
  2. Markieren Sie in Ihrem Nachrichtenhandler Nachrichten explizit als abgeschlossen oder geben Sie sie frei.

    @JmsListener(destination = "QUEUE_NAME", containerFactory = "customQueueJmsListenerContainerFactory")
    public void receiveMessage(JmsTextMessage message) throws Exception {
        String event = message.getBody(String.class);
        try {
            logger.info("Received event: {}", event);
            logger.info("Received message: {}", message);
            // by default complete the message
            message.acknowledge();
        } catch (Exception e) {
            logger.error("Exception while processing re-source event: " + event, e);
            JmsAcknowledgeCallback acknowledgeCallback = message.getAcknowledgeCallback();
            // explicitly abandon the message
            acknowledgeCallback.setAckType(MODIFIED_FAILED);
            message.setAcknowledgeCallback(acknowledgeCallback);
            message.acknowledge();
            throw e;
        }
    }
    

Konfigurationsprobleme

Automatische Konfiguration des Servicebus-JMS deaktivieren

Problembeschreibung

Einige Benutzer importieren einige Spring Cloud Azure Starter für die automatische Konfiguration eines anderen Azure-Diensts als ServiceBus JMS. Sie verwenden auch das Spring-JMS-Framework, ohne dass Service Bus JMS erforderlich ist. Wenn die Anwendung dann versucht, zu starten, werden die folgenden Ausnahmen ausgelöst:

Caused by: java.lang.IllegalArgumentException: 'spring.jms.servicebus.connection-string' should be provided
    at com.azure.spring.cloud.autoconfigure.jms.properties.AzureServiceBusJmsProperties.afterPropertiesSet(AzureServiceBusJmsProperties.java:210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
    ... 98 more

Ursachenanalyse

Dieses Problem tritt auf, da alle Spring Cloud Azure-Autokonfigurationsklassen in dasselbe Modul eingefügt werden, daher importiert jeder Spring Cloud Azure Starter tatsächlich alle diese Autokonfiguration, die auch Service Bus JMS enthält. Wenn die Anwendung dann die Spring JMS-API verwendet, erfüllt sie die Bedingung Autokonfiguration von ServiceBus JMS und löst sie aus. Für Benutzer, die nicht beabsichtigen, spring-cloud-azure-starter-servicebus-jmszu verwenden, sind die Eigenschaftsbedingungen nicht erfüllt, da es keinen Grund für sie gibt, Service Bus für JMS zu konfigurieren. Diese Situation löst die Ausnahmen aus.

Lösung

Spring Cloud Azure for Service Bus JMS bietet eine Eigenschaft zum Aktivieren oder Deaktivieren der automatischen Konfiguration. Sie können diese Funktionalität nach Bedarf deaktivieren, indem Sie die folgende Eigenschaftseinstellung verwenden:

spring.jms.servicebus.enabled=false

Konfigurieren von Nachrichtenattributen

Wie legen Sie den Inhaltstyp ausgehender Nachrichten fest?

Um den Inhaltstyp zu konfigurieren, passen Sie den Nachrichtenkonverter an, um das Inhaltstyp-Attribut beim Konvertieren von Nachrichten zu ändern. Der folgende Code akzeptiert Bytenachrichten als Beispiel.

Passen Sie zunächst den Nachrichtenkonverter an, der in der JmsTemplateverwendet werden soll, wie im folgenden Beispiel gezeigt:

public class CustomMappingJackson2MessageConverter extends MappingJackson2MessageConverter {

    public static final String CONTENT_TYPE = "application/json";

    public CustomMappingJackson2MessageConverter() {
        this.setTargetType(MessageType.BYTES);
    }

    @Override
    protected BytesMessage mapToBytesMessage(Object object, Session session, ObjectWriter objectWriter)
            throws JMSException, IOException {
        final BytesMessage message = super.mapToBytesMessage(object, session, objectWriter);
        JmsBytesMessage msg = (JmsBytesMessage) message;
        AmqpJmsMessageFacade facade = (AmqpJmsMessageFacade) msg.getFacade();
        facade.setContentType(Symbol.valueOf(CONTENT_TYPE));
        return msg;
    }
}

Deklarieren Sie dann die Bean für den benutzerdefinierten Nachrichtenkonverter, wie im folgenden Beispiel gezeigt:

@Configuration(proxyBeanMethods = false)
public class CustomJmsConfiguration {

    @Bean
    public MessageConverter messageConverter() {
        return new CustomMappingJackson2MessageConverter();
    }
}

Wie legt man den Eigenschaftsnamen der Typ-ID für MappingJackson2MessageConverter fest?

Das type-id-property-name-Attribut ermöglicht es der MappingJackson2MessageConverter, zu bestimmen, welche Klasse zum Deserialisieren der Nachrichtennutzlast verwendet werden soll. Beim Serialisieren jedes Java-Objekts in eine Spring Message-Nutzlast speichert der Konverter den Nutzlasttyp in einer Nachrichteneigenschaft mit dem Eigenschaftsnamen, der von type-id-property-nameaufgezeichnet wird. Anschließend liest der Konverter beim Deserialisieren der Nachricht die Typ-ID aus der Nachricht und deserialisiert sie.

Um die type-id-property-namefestzulegen, deklarieren Sie Ihre eigene MappingJackson2MessageConverter Bean, und konfigurieren Sie diese Eigenschaft, wie im folgenden Beispiel gezeigt:

@Configuration(proxyBeanMethods = false)
public class CustomJmsConfiguration {

    @Bean
    public MessageConverter jacksonJmsMessageConverter()
    {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setTypeIdPropertyName("your-custom-type-id-property-name");
        return converter;
    }
}

Duplikaterkennung

Azure Service Bus unterstützt doppelte Erkennung, die die MessageId-Eigenschaft anwendet, um Nachrichten eindeutig zu identifizieren und die duplizierten Duplikate zu verwerfen, die an Service Bus gesendet werden.

Für die JMS-API sollten Sie jedoch nicht die JMS-Nachrichten-ID festlegen, die in JMS-Spezifikationen als unzulässige angesehen wird. Dieses Feature wird für Spring Cloud Azure Service Bus JMS Starter derzeit nicht unterstützt.

Weitere Aktualisierungen zu dieser Funktion finden Sie im GitHub-Issue.

Aktivieren der AMQP-Transportprotokollierung

Weitere Informationen finden Sie im Abschnitt Aktivieren der AMQP-Transportprotokollierung Abschnitt Problembehandlung bei Service Bus-Problemen.

Weitere Hilfe erhalten

Weitere Informationen zu den Möglichkeiten zum Erreichen des Supports finden Sie unter Support- im Stammverzeichnis des Repositorys.

Ressourcen für Spring Cloud Azure Service Bus JMS Starter

GitHub-Issues einreichen

Bei der Einreichung von GitHub-Problemen werden die folgenden Details angefordert:

  • Service Bus-Konfiguration/ Namespaceumgebung
    • Welche Stufe ist der Namespace (Standard oder Premium)?
    • Welche Art von Messaging-Entität wird verwendet (Warteschlange oder Thema)? und deren Konfiguration.
    • Was ist die durchschnittliche Größe jeder Nachricht?
  • Wie sieht das Datenverkehrsmuster aus? (d. h., die Anzahl der Nachrichten pro Minute und ob der Client immer ausgelastet ist oder langsame Verkehrszeiträume hat.)
  • Reproduktionscode und Schritte
    • Dies ist wichtig, da wir das Problem in unserer Umgebung oft nicht reproduzieren können.
  • Protokolle