Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Deze handleiding bevat gedetailleerde informatie waarmee u kunt communiceren met Azure Service Bus met behulp van de API Java Message Service (JMS) 2.0.
Als java-ontwikkelaar kunt u de volgende artikelen lezen als u nog geen gebruik hebt gemaakt van Azure Service Bus.
| Aan de slag | Concepten |
|---|---|
|
programmeermodel voor Java Message Service (JMS)
Het programmeermodel Java Message Service-API wordt beschreven in de volgende secties:
Opmerking
De Azure Service Bus Premium-laag ondersteunt JMS 1.1 en JMS 2.0.
Azure Service Bus - Standard-laag biedt ondersteuning voor beperkte JMS 1.1-functionaliteit. Zie deze documentatie voor meer informatie.
JMS - Bouwstenen
Gebruik de volgende bouwstenen om te communiceren met de JMS-toepassing.
Opmerking
Deze handleiding is aangepast aan de Oracle Java EE 6 Tutorial for Java Message Service (JMS).
Raadpleeg deze zelfstudie voor een beter begrip van de Java Message Service (JMS).
Verbindingsfabriek
Opmerking
De azure-servicebus-jms bibliotheek is beschikbaar in twee varianten: com.azure:azure-servicebus-jms (versie 2.0.0+) voor Jakarta EE (jakarta.jms.*) en com.microsoft.azure:azure-servicebus-jms (versie 1.0.x) voor Java EE (javax.jms.*). Zie Jakarta EE en javax-ondersteuning voor hulp bij het kiezen van het juiste artefact.
De client gebruikt het verbindingsfactory-object om verbinding te maken met de JMS-provider. De connection factory omvat een reeks configuratieparameters voor verbindingen die de beheerder definieert.
Elke verbindingsfactory is een exemplaar van de ConnectionFactory, QueueConnectionFactoryof TopicConnectionFactory interface.
Om de verbinding met Azure Service Bus te vereenvoudigen, worden deze interfaces geïmplementeerd via respectievelijk ServiceBusJmsConnectionFactory, ServiceBusJmsQueueConnectionFactory of ServiceBusJmsTopicConnectionFactory.
Belangrijk
Java toepassingen die gebruikmaken van de JMS 2.0-API, kunnen verbinding maken met Azure Service Bus met behulp van de verbindingsreeks of met behulp van een TokenCredential om gebruik te maken van Microsoft Entra ondersteunde verificatie. Wanneer u Microsoft Entra ondersteunde verificatie gebruikt, moet u zo nodig rollen en machtigingen toewijzen aan de identiteit.
- Door het systeem toegewezen beheerde identiteit
- Door de gebruiker toegewezen beheerde identiteit
- Service-principal
Maak een door het systeem toegewezen beheerde identiteit in Azure en gebruik deze identiteit om een TokenCredential.
TokenCredential tokenCredential = new DefaultAzureCredentialBuilder().build();
U kunt de verbindingsfactory instantiëren met de volgende parameters:
- Tokenreferentie: vertegenwoordigt een referentie die een OAuth-token kan leveren.
- Host: de hostnaam van de Azure Service Bus Premium-laagnaamruimte.
- Kenmerkenbundel ServiceBusJmsConnectionFactorySettings, die het volgende bevat:
-
connectionIdleTimeoutMS- Time-out voor inactieve verbinding in milliseconden. -
traceFrames- Booleaanse vlag voor het verzamelen van AMQP-traceringsframes voor foutopsporing. - Andere configuratieparameters.
-
Maak de factory, zoals wordt weergegeven in het volgende voorbeeld. De tokenreferenties en host zijn vereiste parameters, maar de andere eigenschappen zijn optioneel.
String host = "<YourNamespaceName>.servicebus.windows.net";
ConnectionFactory factory = new ServiceBusJmsConnectionFactory(tokenCredential, host, null);
JMS-bestemming
Een bestemming is het object dat een client gebruikt om het doel op te geven van de berichten die de client produceert en de bron van de berichten die deze verbruikt.
Bestemmingen komen overeen met entiteiten in Azure Service Bus, zoals wachtrijen (in punt-naar-puntscenario's) en topics (in pub-subscenario's).
Verbindingen
Een verbinding omvat een virtuele verbinding met een JMS-provider. Met Azure Service Bus is er sprake van een stateful verbinding tussen de toepassing en Azure Service Bus via AMQP.
Maak een verbinding vanuit de verbindingsfabriek, zoals wordt weergegeven in het volgende voorbeeld:
Connection connection = factory.createConnection();
Sessies
Een sessie is een context met één thread voor het produceren en gebruiken van berichten. Gebruik deze om berichten, berichtproducenten en consumenten te maken. Het biedt ook een transactionele context om verzenden en ontvangen te groeperen in een atomische werkeenheid.
Maak een sessie op basis van het verbindingsobject, zoals wordt weergegeven in het volgende voorbeeld:
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Opmerking
JMS-API biedt geen ondersteuning voor het ontvangen van berichten van service bus-wachtrijen of onderwerpen waarvoor berichtensessies zijn ingeschakeld.
Sessiemodi
Maak een sessie met een van de volgende modi.
| Sessiemodi | Gedrag |
|---|---|
| Session.AUTO_ACKNOWLEDGE | De sessie bevestigt automatisch de ontvangst van een bericht van een client wanneer de sessie succesvol terugkeert van een oproep naar ontvangen, of wanneer de berichtlistener die de sessie aanroept om het bericht te verwerken succesvol terugkeert. |
| Session.KLANT_ERKENNING | De client erkent een verbruikt bericht door de erkenningsmethode van het bericht aan te roepen. |
| Session.DUPS_OK_ACKNOWLEDGE | Deze bevestigingsmodus instrueert de sessie om de bezorging van berichten op een luie manier te bevestigen. |
| Session.SESSION_TRANSACTED | Geef deze waarde door als het argument aan de methode createSession(int sessionMode) in het verbindingsobject om op te geven dat de sessie een lokale transactie moet gebruiken. |
Als u de sessiemodus niet opgeeft, wordt de standaardwaarde Session.AUTO_ACKNOWLEDGE.
JMSContext
Opmerking
JMSContext wordt gedefinieerd als onderdeel van de JMS 2.0-specificatie.
JMSContext combineert de functionaliteit die wordt geboden door het verbindings- en sessieobject. U maakt het op basis van het verbindingsfactoryobject.
JMSContext context = connectionFactory.createContext();
JMSContext-modi
Net als het sessieobject kunt u de JMSContext maken met dezelfde bevestigingsmodi als vermeld in sessiemodi.
JMSContext context = connectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE);
Als u geen modus opgeeft, wordt de standaardwaarde JMSContext.AUTO_ACKNOWLEDGE.
JMS-berichtproducenten
Een berichtproducent is een object dat u maakt met behulp van een JMSContext of een sessie. Gebruik deze om berichten naar een bestemming te verzenden.
U kunt het maken als een zelfstandig object, zoals wordt weergegeven in het volgende voorbeeld:
JMSProducer producer = context.createProducer();
U kunt het ook tijdens runtime maken wanneer u een bericht wilt verzenden.
context.createProducer().send(destination, message);
JMS-berichtgebruikers
Een berichtconsumer is een object dat door een JMSContext of een sessie wordt gemaakt. Hiermee kunt u berichten ontvangen die naar een bestemming zijn verzonden. Maak deze, zoals wordt weergegeven in het volgende voorbeeld:
JMSConsumer consumer = context.createConsumer(dest);
Synchrone ontvangst via receive()-methode
De gebruiker van het bericht biedt een synchrone manier om berichten van de bestemming te ontvangen via de receive() methode.
Als u geen argumenten of time-out opgeeft of als u een time-out van 0 opgeeft, blokkeert de consument voor onbepaalde tijd, tenzij het bericht binnenkomt of de verbinding is verbroken (afhankelijk van wat eerder is).
Message m = consumer.receive();
Message m = consumer.receive(0);
Wanneer u een niet-nul-positief argument opgeeft, blokkeert de consument totdat die timer verloopt.
Message m = consumer.receive(1000); // time out after one second.
Asynchrone ontvangst met JMS-berichtlisteners
Een berichtenlistener is een object dat u gebruikt voor asynchrone verwerking van berichten op een bestemming. Hiermee wordt de MessageListener interface geïmplementeerd, die de onMessage methode bevat waarin de specifieke bedrijfslogica moet leven.
U moet een berichtlistenerobject instantiëren en registreren bij een specifieke berichtgebruiker met behulp van de setMessageListener methode.
Listener myListener = new Listener();
consumer.setMessageListener(myListener);
Gebruiken vanuit onderwerpen
U maakt JMS-berichtconsumenten op basis van een bestemming, wat een wachtrij of een onderwerp kan zijn.
Consumenten in wachtrijen zijn simpelweg objecten aan de clientzijde die zich in de context van de sessie (en verbinding) bevinden tussen de clienttoepassing en Azure Service Bus.
Onderwerpen voor consumenten hebben echter twee delen.
- Een object aan de clientzijde dat zich in de context van de sessie (of JMSContext) bevindt en
- Een abonnement dat een entiteit is in Azure Service Bus.
De abonnementen worden hier beschreven en kunnen een van de volgende typen zijn:
- Gedeelde duurzame abonnementen
- Gedeelde niet-duurzame abonnementen
- Niet-gedeelde duurzame abonnementen
- Niet-gedeelde niet-duurzame abonnementen
JMS-wachtrijbrowsers
De JMS-API biedt een QueueBrowser object dat de toepassing kan gebruiken om door de berichten in de wachtrij te bladeren en de headerwaarden voor elk bericht weer te geven.
U kunt een wachtrijbrowser maken met behulp van de JMSContext, zoals wordt weergegeven in het volgende voorbeeld:
QueueBrowser browser = context.createBrowser(queue);
Opmerking
JMS-API biedt geen API om door een onderwerp te bladeren.
Deze beperking bestaat omdat het onderwerp zelf de berichten niet opslaat. Zodra het bericht naar het onderwerp wordt verzonden, wordt het doorgestuurd naar de juiste abonnementen.
JMS-berichtselectoren
Ontvangende toepassingen kunnen berichtkiezers gebruiken om de berichten te filteren die ze ontvangen. Met behulp van berichtkiezers offload de ontvangende toepassing het werk van het filteren van berichten naar de JMS-provider (in dit geval Azure Service Bus) in plaats van die verantwoordelijkheid zelf te nemen.
U kunt selectors gebruiken bij het maken van een van de volgende consumenten:
- Gedeeld duurzaam abonnement
- Niet-gedeeld duurzaam abonnement
- Gedeeld niet-duurzaam abonnement
- Niet-gedeeld niet-duurzaam abonnement
- Wachtrijconsumer
- Wachtrijbrowser
Opmerking
Service Bus selectors bieden geen ondersteuning voor LIKE en BETWEEN SQL-trefwoorden.
Geplande berichten (verzendvertraging)
JMS 2.0 ondersteunt het plannen van een bericht voor toekomstige bezorging met behulp van de setDeliveryDelay methode op een MessageProducer of JMSProducer. Wanneer u deze eigenschap instelt, accepteert Service Bus het bericht, maar wordt het alleen zichtbaar voor consumenten nadat de vertragingsperiode is verstreken.
MessageProducer producer = session.createProducer(queue);
// Schedule a message for delivery 30 seconds from now
producer.setDeliveryDelay(30000);
producer.send(session.createTextMessage("Scheduled message"));
Zie QueueScheduledSend.java in de opslagplaats azure-servicebus-jms-samples voor een volledig werkend voorbeeld.
Selectie en veerkracht van verbindingsfabrieken
Wanneer u ServiceBusJmsConnectionFactory gebruikt in Spring Boot of andere frameworks die JMS-verbindingen beheren, kies dan de juiste verbindingsfactory-wrapper voor afzenders en listeners om een betrouwbare werking te garanderen.
Aanbevolen configuratie
| Role | Verbindingsfabriek | Waarom |
|---|---|---|
Afzenders (JmsTemplate) |
CachingConnectionFactory Verpakking ServiceBusJmsConnectionFactory |
JmsTemplate maakt en sluit standaard een verbinding per verzenden.
CachingConnectionFactory onderhoudt één enkele AMQP-verbinding en slaat sessies op in de cache, waardoor verbindingsverloop wordt voorkomen dat de broker-resources onder belasting kan uitputten. |
Listeners (@JmsListener, DefaultMessageListenerContainer) |
Onbewerkt ServiceBusJmsConnectionFactory (onverpakt) |
Elke listenercontainer krijgt een eigen AMQP-verbinding met een onafhankelijke levenscyclus. Als een verbinding mislukt (verloop van token, gateway-upgrade, netwerkstoring), wordt alleen die listener beïnvloed en wordt de verbinding automatisch opnieuw tot stand gebracht. |
Wat te vermijden voor luisteraars
Warning
Gebruik nooit SingleConnectionFactory met listenercontainers. Het dwingt alle listeners om één JMS-verbinding te delen. Als deze verbinding om welke reden dan ook wordt onderbroken, verliezen alle listeners tegelijkertijd de verbinding en kunnen ze niet onafhankelijk herstellen. Gebruik de onbewerkte ServiceBusJmsConnectionFactory gegevens zodat elke listenercontainer een eigen verbinding beheert.
CachingConnectionFactory in listenercontainers kunnen ook problemen optreden omdat sessies in de cache mogelijk verwijzen naar een verouderde onderliggende verbinding. Voor listeners zorgt de raw factory ervoor dat elke container onafhankelijk een nieuwe verbinding kan maken.
Spring Cloud Azure standaardinstellingen
Als u (versie 6.2.0+) gebruikt spring-cloud-azure-starter-servicebus-jms , past de starter deze fabrieksscheiding standaard toe:
spring.jms.servicebus.pool.enabled |
spring.jms.cache.enabled |
Fabriek van afzender | Listenerfabriek |
|---|---|---|---|
| (niet ingesteld) | (niet ingesteld) | CachingConnectionFactory |
ServiceBusJmsConnectionFactory |
| (niet ingesteld) | true |
CachingConnectionFactory |
CachingConnectionFactory |
| (niet ingesteld) | false |
ServiceBusJmsConnectionFactory |
ServiceBusJmsConnectionFactory |
true |
(niet ingesteld) | JmsPoolConnectionFactory |
JmsPoolConnectionFactory |
In oudere versies (pre-6.2.0) gebruiken zowel afzenders als listeners ServiceBusJmsConnectionFactory standaard, waardoor afzenders per verzending een nieuwe verbinding aanmaken.
Een uitzonderingslistener toevoegen
Zonder uitzonderingslistener zijn verbindingsdruppels volledig stil. Voeg een jakarta.jms.ExceptionListener toe aan zowel de afzender- als de luisteraarfactories voor waarneembaarheid.
connection.setExceptionListener(exception -> {
log.error("JMS connection error: {}", exception.getMessage(), exception);
});
Stel in Spring Boot de uitzonderingslistener in op de CachingConnectionFactory (voor afzenders) en de DefaultJmsListenerContainerFactory (voor listeners).
Zie het voorbeeld Spring Boot JMS Resilience sample in de opslagplaats azure-servicebus-jms-samples voor een volledig werkend voorbeeld met al deze patronen.
Wachtrijen voor ongeleverde berichten
Elk wachtrij- en onderwerpabonnement in Azure Service Bus heeft een gekoppelde adletterwachtrij (DLQ). Het systeem verplaatst automatisch berichten die het niet kan leveren of verwerken naar de DLQ. Het systeem verplaatst bijvoorbeeld een bericht naar de DLQ wanneer het bericht het maximale aantal bezorging overschrijdt of de time-to-live (TTL) verloopt.
Belangrijk
Als u verlopen TTL-berichten naar de DLQ wilt verplaatsen, schakelt u dead-lettering bij het verlopen van berichten in voor de wachtrij of het abonnement. Zonder deze instelling worden verlopen berichten stilletjes verwijderd. Zie voor configuratiestappen Dead Lettering inschakelen voor een wachtrij of abonnement.
In JMS benadert u de DLQ als een afzonderlijke bestemming door het volledige pad te construeren en er een JmsQueue mee te maken. Er is geen speciale API vereist.
DLQ-padopmaak voor wachtrij:
<queue-name>/$deadletterqueue
Indeling van het DLQ-pad voor onderwerpabonnement:
<topic-name>/Subscriptions/<subscription-name>/$deadletterqueue
Voorbeeld: verbruiken vanuit de wachtrij voor dode brieven van een wachtrij:
import org.apache.qpid.jms.JmsQueue;
// Construct the DLQ path for a queue named "orders"
String dlqPath = "orders/$deadletterqueue";
JmsQueue dlqDestination = new JmsQueue(dlqPath);
// Create a consumer on the DLQ and receive messages
MessageConsumer dlqConsumer = session.createConsumer(dlqDestination);
Message message = dlqConsumer.receive(5000);
Niet-geschreven berichten bevatten metagegevenseigenschappen die beschrijven waarom het bericht niet is geschreven:
| Vastgoed | Beschrijving |
|---|---|
DeadLetterReason |
De reden waarom het bericht niet is geschreven (bijvoorbeeld TTLExpiredException of MaxDeliveryCountExceeded). |
DeadLetterErrorDescription |
Een door mensen leesbare beschrijving van de reden van de dode letter. |
Lees deze eigenschappen met behulp van message.getStringProperty():
String reason = message.getStringProperty("DeadLetterReason");
String description = message.getStringProperty("DeadLetterErrorDescription");
Zie QueueDeadLetterReceive.java in de opslagplaats azure-servicebus-jms-samples voor een volledig werkend voorbeeld.
AMQP-verwijdering en Service Bus-bewerkingstoewijzing
Hier ziet u hoe een AMQP-dispositie vertaalt naar een Service Bus-operatie:
ACCEPTED = 1; -> Complete()
REJECTED = 2; -> DeadLetter()
RELEASED = 3; (just unlock the message in service bus, will then get redelivered)
MODIFIED_FAILED = 4; -> Abandon() which increases delivery count
MODIFIED_FAILED_UNDELIVERABLE = 5; -> Defer()
Samenvatting
Deze ontwikkelaarshandleiding laat zien hoe Java clienttoepassingen die gebruikmaken van Java Message Service (JMS) verbinding kunnen maken met Azure Service Bus.
Volgende stappen
Zie de volgende artikelen voor meer informatie over Azure Service Bus en details over Java Message Service -entiteiten (JMS):
- Keuze tussen JMS en de systeemeigen SDK voor Azure Service Bus
- Service Bus - Wachtrijen, onderwerpen en abonnementen
- Service Bus - Java Message Service-entiteiten
- AMQP 1.0-ondersteuning in Azure Service Bus
- Handleiding voor ontwikkelaars van Service Bus AMQP 1.0
- Aan de slag met Service Bus-wachtrijen
- Java Message Service API externe Oracle-documentatie
- Meer informatie over het migreren van ActiveMQ naar Service Bus