Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este guia fornece informações detalhadas para o ajudar a ter sucesso na comunicação com o Azure Service Bus utilizando a API Java Message Service (JMS) 2.0.
Como programador Java, se és novo no Azure Service Bus, considera ler os seguintes artigos.
| Como Começar | Conceitos |
|---|---|
Modelo de programação Java Message Service (JMS)
O modelo de programação da API do Java Message Service é descrito nas seguintes secções:
Observação
A camada Premium do Barramento de Serviço do Azure suporta JMS 1.1 e JMS 2.0.
O Barramento de Serviço do Azure - camada Standard suporta funcionalidade limitada do JMS 1.1. Para mais detalhes, consulte esta documentação.
JMS - Blocos de construção
Use os seguintes blocos de construção para comunicar com a aplicação JMS.
Observação
Este guia é adaptado do tutorial Oracle Java EE 6 para Java Message Service (JMS).
Para uma melhor compreensão do Java Message Service (JMS), consulte este tutorial.
Fábrica de conexões
Observação
A azure-servicebus-jms biblioteca está disponível em duas variantes: com.azure:azure-servicebus-jms (versão 2.0.0+) para Jakarta EE (jakarta.jms.*) e com.microsoft.azure:azure-servicebus-jms (versão 1.0.x) para Java EE (javax.jms.*). Para orientações sobre como escolher o artefato certo, consulte Jakarta EE e suporte javax.
O cliente utiliza o objeto de fábrica de ligação para se ligar ao fornecedor JMS. A fábrica de ligação encapsula um conjunto de parâmetros de configuração de ligação que o administrador define.
Cada fábrica de ligação é uma instância do ConnectionFactory, QueueConnectionFactory, ou TopicConnectionFactory interface.
Para simplificar a ligação a Azure Service Bus, estas interfaces são implementadas através de ServiceBusJmsConnectionFactory, ServiceBusJmsQueueConnectionFactory ou ServiceBusJmsTopicConnectionFactory, respetivamente.
Importante
Java aplicações que utilizam a API JMS 2.0 podem ligar-se a Azure Service Bus usando o cadeia de ligação ou usando um TokenCredential para aproveitar a autenticação Microsoft Entra suportada. Quando usar autenticação Microsoft Entra apoiada, certifique-se de atribuir papéis e permissões à identidade conforme necessário.
- Identidade gerenciada atribuída pelo sistema
- Identidade Gerida Atribuída pelo Utilizador
- Entidade de Serviço
Crie uma identidade gerida atribuída pelo sistema no Azure e use essa identidade para criar um TokenCredential.
TokenCredential tokenCredential = new DefaultAzureCredentialBuilder().build();
Pode instanciar a fábrica de ligação com os seguintes parâmetros:
- Credencial de token - Representa uma credencial capaz de fornecer um token OAuth.
- Host - O nome de host do namespace de nível Premium do Azure Service Bus.
- ServiceBusJmsConnectionFactorySettings, que contém:
-
connectionIdleTimeoutMS- tempo limite da ligação inativa em milissegundos. -
traceFrames- flag booleano para recolher tramas de traço AMQP para depuração. - Outros parâmetros de configuração.
-
Crie a fábrica como mostrado no exemplo seguinte. A credencial de token e o host são parâmetros necessários, mas as outras propriedades são opcionais.
String host = "<YourNamespaceName>.servicebus.windows.net";
ConnectionFactory factory = new ServiceBusJmsConnectionFactory(tokenCredential, host, null);
Destino JMS
Um destino é o objeto que um cliente usa para especificar o destino das mensagens que produz e a origem das mensagens que consome.
Destinos mapeados para entidades no Barramento de Serviço do Azure - filas (em cenários ponto a ponto) e tópicos (em cenários pub-sub).
Conexões
Uma conexão encapsula uma ligação virtual com um fornecedor de JMS. Com o Barramento de Serviço do Azure, ele representa uma conexão com monitoração de estado entre o aplicativo e o Barramento de Serviço do Azure sobre AMQP.
Crie uma ligação a partir da fábrica de ligações, como mostrado no seguinte exemplo:
Connection connection = factory.createConnection();
Sessões
Uma sessão é um contexto de thread único para produzir e consumir mensagens. Use-o para criar mensagens, produtores de mensagens e consumidores. Também fornece um contexto transacional para agrupar envios e receitas numa unidade atómica de trabalho.
Crie uma sessão a partir do objeto de conexão, como mostrado no seguinte exemplo:
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Observação
A API JMS não suporta o recebimento de mensagens de filas de barramento de serviço ou tópicos com sessões de mensagens habilitadas.
Modos de sessão
Crie uma sessão com qualquer um dos seguintes modos.
| Modos de sessão | Comportamento |
|---|---|
| Session.AUTO_ACKNOWLEDGE | A sessão reconhece automaticamente a receção de uma mensagem por parte do cliente, seja quando a sessão regressa com sucesso de uma chamada para receber ou quando o ouvinte da mensagem que a sessão chama para processar a mensagem retorna com sucesso. |
| Session.CLIENT_ACKNOWLEDGE (Reconhecimento do Cliente) | O cliente reconhece uma mensagem consumida chamando o método de reconhecimento da mensagem. |
| Session.DUPS_OK_ACKNOWLEDGE | Este modo de confirmação instrui a sessão a reconhecer preguiçosamente a entrega de mensagens. |
| Session.SESSION_TRANSACTED | Passe este valor como argumento ao método createSession(int sessionMode) no objeto Connection para especificar que a sessão deve usar uma transação local. |
Se não especificares o modo de sessão, o padrão é Session.AUTO_ACKNOWLEDGE.
JMSContext
Observação
JMSContext é definido como parte da especificação JMS 2.0.
JMSContext combina a funcionalidade fornecida pelo objeto de conexão e sessão. Cria-se a partir do objeto connection factory.
JMSContext context = connectionFactory.createContext();
Modos JMSContext
Tal como o objeto Session , pode criar o JMSContext com os mesmos modos de reconhecimento mencionados nos modos Session.
JMSContext context = connectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE);
Se não especificares um modo, o padrão é JMSContext.AUTO_ACKNOWLEDGE.
Produtores de mensagens JMS
Um produtor de mensagens é um objeto que se cria usando um JMSContext ou uma Session. Use-o para enviar mensagens para um destino.
Pode criá-lo como um objeto autónomo, como mostrado no seguinte exemplo:
JMSProducer producer = context.createProducer();
Ou podes criá-lo em tempo de execução quando precisares de enviar uma mensagem.
context.createProducer().send(destination, message);
Consumidores de mensagens JMS
Um consumidor de mensagens é um objeto criado por um JMSContext ou uma Session. Use-o para receber mensagens enviadas para um destino. Crie-o como mostrado no seguinte exemplo:
JMSConsumer consumer = context.createConsumer(dest);
Recebimento síncrono via método receive()
O consumidor de mensagens fornece uma maneira síncrona de receber mensagens do destino por meio do receive() método.
Se não especificar argumentos ou timeout, ou se especificar um timeout de 0, o consumidor bloqueia indefinidamente a menos que a mensagem chegue, ou a ligação seja quebrada (o que for mais antigo).
Message m = consumer.receive();
Message m = consumer.receive(0);
Quando apresentas um argumento positivo diferente de zero, o consumidor bloqueia até esse temporizador expirar.
Message m = consumer.receive(1000); // time out after one second.
Receções assíncronas com ouvintes de mensagens JMS
Um ouvinte de mensagens é um objeto que utiliza para o tratamento assíncrono de mensagens num destino. Implementa a interface MessageListener, que contém o método onMessage onde a lógica de negócios específica deve estar implementada.
Deve instanciar um objeto ouvinte de mensagens e registá-lo contra um consumidor específico de mensagens usando o setMessageListener método.
Listener myListener = new Listener();
consumer.setMessageListener(myListener);
Consumir a partir de tópicos
Cria-se Consumidores de Mensagens JMS contra um destino, que pode ser uma fila ou um tópico.
Os consumidores em filas são simplesmente objetos do lado do cliente que vivem no contexto da Sessão (e da Ligação) entre a aplicação cliente e o Azure Service Bus.
Os consumidores sobre temas, no entanto, têm duas partes -
- Um objeto do lado do cliente que vive no contexto da Sessão (ou JMSContext), e
- Uma assinatura que é uma entidade no Azure Service Bus.
As subscrições estão documentadas aqui e podem ser de um dos seguintes tipos:
- Subscrições duradouras partilhadas
- Subscrições partilhadas não duráveis
- Subscrições duradouras não partilhadas
- Subscrições não partilhadas não duradouras
Navegadores de fila JMS
A API JMS fornece um QueueBrowser objeto que a aplicação pode usar para navegar pelas mensagens na fila e mostrar os valores do cabeçalho de cada mensagem.
Pode criar um Navegador de Filas usando o JMSContext, como mostrado no seguinte exemplo:
QueueBrowser browser = context.createBrowser(queue);
Observação
A API JMS não fornece uma API para navegar em um tópico.
Esta limitação existe porque o próprio tema não armazena as mensagens. Assim que a mensagem é enviada para o tópico, ela é encaminhada para as assinaturas apropriadas.
Seletores de mensagens JMS
As aplicações recetoras podem usar seletores de mensagens para filtrar as mensagens que recebem. Ao usar seletores de mensagens, a aplicação recetora transfere o trabalho de filtragem das mensagens para o fornecedor JMS (neste caso, Azure Service Bus) em vez de assumir essa responsabilidade por si própria.
Pode usar seletores ao criar qualquer um dos seguintes consumidores:
- Subscrição duradoura partilhada
- Subscrição duradoura não partilhada
- Subscrição partilhada não durável
- Subscrição não partilhada não duradoura
- Consumidor da fila
- Navegador de filas
Observação
Service Bus seletores não suportam palavras-chave SQL LIKE e BETWEEN.
Mensagens agendadas (atraso na entrega)
O JMS 2.0 suporta o agendamento de uma mensagem para entrega futura usando o setDeliveryDelay método num MessageProducer ou JMSProducer. Quando define esta função, o Service Bus aceita a mensagem mas só a torna visível para os consumidores após o período de atraso terminar.
MessageProducer producer = session.createProducer(queue);
// Schedule a message for delivery 30 seconds from now
producer.setDeliveryDelay(30000);
producer.send(session.createTextMessage("Scheduled message"));
Para uma amostra funcional completa, veja QueueScheduledSend.java no repositório azure-servicebus-jms-samples.
Seleção e resiliência da fábrica de ligações
Quando usar ServiceBusJmsConnectionFactory o Spring Boot ou outros frameworks que gerem ligações JMS, escolha o wrapper de fábrica de ligação certo para remetentes e ouvintes para garantir uma operação fiável.
Configuração recomendada
| Role | Fábrica de conexões | Porquê |
|---|---|---|
Remetentes (JmsTemplate) |
CachingConnectionFactory Envolvimento ServiceBusJmsConnectionFactory |
JmsTemplate cria e fecha uma ligação por envio por defeito.
CachingConnectionFactory mantém uma única ligação AMQP e armazena em cache as sessões, evitando o churn de ligação que pode esgotar os recursos do broker sob carga. |
Ouvintes (@JmsListener, DefaultMessageListenerContainer) |
Cru ServiceBusJmsConnectionFactory (desembrulhado) |
Cada contentor ouvinte tem a sua própria ligação AMQP com ciclo de vida independente. Se uma ligação falhar (expiração do token, atualização do gateway, blip de rede), apenas esse ouvinte é afetado, e o Spring recria a ligação automaticamente. |
O que evitar para os ouvintes
Advertência
Nunca uses SingleConnectionFactory com recipientes de ouvinte. Obriga todos os ouvintes a partilhar uma única ligação JMS. Se essa ligação for interrompida por qualquer motivo, todos os ouvintes perdem a ligação simultaneamente e não conseguem recuperar de forma independente. Usa o raw ServiceBusJmsConnectionFactory para que cada contentor de ouvinte gere a sua própria ligação.
CachingConnectionFactory No ouvinte, os contentores também podem causar problemas porque sessões em cache podem referir-se a uma ligação subjacente obsoleta. Para os ouvintes, a fábrica de crus garante que cada recipiente pode criar uma nova ligação de forma independente.
Spring Cloud Azure predefinidos
Se usares spring-cloud-azure-starter-servicebus-jms (versão 6.2.0+), o starter aplica esta separação de fábrica por defeito:
spring.jms.servicebus.pool.enabled |
spring.jms.cache.enabled |
Fábrica de emissores | Fábrica de ouvintes |
|---|---|---|---|
| (não definido) | (não definido) | CachingConnectionFactory |
ServiceBusJmsConnectionFactory |
| (não definido) | true |
CachingConnectionFactory |
CachingConnectionFactory |
| (não definido) | false |
ServiceBusJmsConnectionFactory |
ServiceBusJmsConnectionFactory |
true |
(não definido) | JmsPoolConnectionFactory |
JmsPoolConnectionFactory |
Em versões mais antigas (anteriores à 6.2.0), tanto os remetentes como os ouvintes usam ServiceBusJmsConnectionFactory por defeito, o que faz com que os remetentes criem uma nova ligação por envio.
Adicionar um ouvinte de exceção
Sem exceção, ouvinte, as falhas de ligação são completamente silenciosas. Adicione a jakarta.jms.ExceptionListener tanto às fábricas de emissores como de ouvintes para observabilidade:
connection.setExceptionListener(exception -> {
log.error("JMS connection error: {}", exception.getMessage(), exception);
});
No Spring Boot, defina o ouvinte de exceção em ( CachingConnectionFactory para emissores) e ( DefaultJmsListenerContainerFactory para ouvintes).
Para uma amostra funcional completa que mostre todos estes padrões, consulte a amostra Spring Boot JMS Resiliency no repositório azure-servicebus-jms-samples.
Filas de letra morta
Cada fila e subscrição de tópicos em Azure Service Bus tem uma fila dead letter queue (DLQ) associada. O sistema move automaticamente mensagens que não consegue entregar ou processar para o DLQ. Por exemplo, o sistema move uma mensagem para o DLQ quando a mensagem ultrapassa o número máximo de entregas ou quando o seu tempo de vida (TTL) expira.
Importante
Para mover mensagens expiradas TTL para o DLQ, ative a dead-letter no momento do término da mensagem para a fila ou subscrição. Sem esta configuração, o sistema descarta silenciosamente mensagens expiradas. Para os passos de configuração, consulte Ativar letramento morto para fila ou subscrição.
No JMS, acedes ao DLQ como destino separado construindo o caminho completo e criando um JmsQueue com ele. Não é necessária nenhuma API especial.
Formato do caminho DLQ da fila:
<queue-name>/$deadletterqueue
Subscrição do tópico Formato do caminho DLQ:
<topic-name>/Subscriptions/<subscription-name>/$deadletterqueue
Exemplo - consumir a partir da fila de letras mortas de uma fila:
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);
Mensagens dead-letter incluem propriedades de metadados que descrevem porque é que a mensagem foi dead-lettered:
| Property | Description |
|---|---|
DeadLetterReason |
A razão pela qual a mensagem estava com letra morta (por exemplo, TTLExpiredException ou MaxDeliveryCountExceeded). |
DeadLetterErrorDescription |
Uma descrição legível para humanos da razão da letra morta. |
Leia estas propriedades usando message.getStringProperty():
String reason = message.getStringProperty("DeadLetterReason");
String description = message.getStringProperty("DeadLetterErrorDescription");
Para uma amostra funcional completa, veja QueueDeadLetterReceive.java no repositório azure-servicebus-jms-samples.
Disposição AMQP e mapeamento da operação do Service Bus
Veja como uma disposição AMQP se traduz em uma operação do Service Bus:
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()
Resumo
Este guia para programadores mostra como aplicações cliente Java que utilizam Java Message Service (JMS) podem ligar-se ao Azure Service Bus.
Próximos passos
Para mais informações sobre o Azure Service Bus e detalhes sobre entidades do Java Message Service (JMS), consulte os seguintes artigos:
- Escolha entre o JMS e o SDK nativo para Azure Service Bus
- Barramento de Serviço - Filas, tópicos e assinaturas
- Service Bus - Entidades do Java Message Service
- Suporte a AMQP 1.0 no Azure Service Bus
- Guia do desenvolvedor do Service Bus AMQP 1.0
- Começar com as filas do Service Bus
- API do Java Message Service (doc Oracle externo)
- Saiba como migrar do ActiveMQ para o Service Bus