Partilhar via


Solucionar problemas do Barramento de Serviço do Azure

Este artigo aborda técnicas de investigação de falhas, simultaneidade, erros comuns para os tipos de credenciais na biblioteca de cliente Java do Barramento de Serviço do Azure e etapas de mitigação para resolver esses erros.

Habilitar e configurar o registro em log

O SDK do Azure para Java oferece uma história de registro consistente para ajudar na solução de erros de aplicativos e ajudar a agilizar sua resolução. Os logs produzidos capturam o fluxo de um aplicativo antes de atingir o estado terminal para ajudar a localizar o problema raiz. Para obter orientação sobre o registro em log, consulte Configurar o log no SDK do Azure para Java e Visão geral da solução de problemas.

Além de habilitar o registro em log, definir o nível de log para VERBOSE ou DEBUG fornece informações sobre o estado da biblioteca. As seções a seguir mostram exemplos de log4j2 e configurações de logback para reduzir o excesso de mensagens quando o log detalhado está habilitado.

Configurar o Log4J 2

Use as seguintes etapas para configurar o Log4J 2:

  1. Adicione as dependências em seu pom.xml usando as do pom.xml de exemplo de registro em log, na seção "Dependências necessárias para Log4j2".
  2. Adicione log4j2.xml à sua pasta src/main/resources.

Configurar o logback

Use as seguintes etapas para configurar o logback:

  1. Adicione as dependências em seu pom.xml usando as do pom.xml de exemplo de log, na seção "Dependências necessárias para logback".
  2. Adicione logback.xml à sua pasta src/main/resources.

Habilitar o log de transporte AMQP

Se habilitar o log do cliente não for suficiente para diagnosticar seus problemas, você poderá habilitar o registro em log em um arquivo na biblioteca AMQP subjacente, Qpid Proton-J. Qpid Proton-J usa java.util.logging. Você pode habilitar o registro em log criando um arquivo de configuração com o conteúdo mostrado na próxima seção. Ou, defina proton.trace.level=ALL e as opções de configuração desejadas para a java.util.logging.Handler implementação. Para obter as classes de implementação e suas opções, consulte Package java.util.logging na documentação do Java 8 SDK.

Para rastrear os quadros de transporte AMQP, defina a PN_TRACE_FRM=1 variável de ambiente.

Exemplo de arquivo logging.properties

O seguinte arquivo de configuração registra a saída de nível TRACE do Proton-J para o arquivo proton-trace.log:

handlers=java.util.logging.FileHandler
.level=OFF
proton.trace.level=ALL
java.util.logging.FileHandler.level=ALL
java.util.logging.FileHandler.pattern=proton-trace.log
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=[%1$tF %1$tr] %3$s %4$s: %5$s %n

Reduzir o registo

Uma maneira de diminuir o registro em log é alterar a verbosidade. Outra maneira é adicionar filtros que excluem logs de pacotes de nomes de logger como com.azure.messaging.servicebus ou com.azure.core.amqp. Para obter exemplos, consulte os arquivos XML nas seções Configurar Log4J 2 e Configurar logback .

Quando você envia um bug, as mensagens de log das classes nos seguintes pacotes são interessantes:

  • com.azure.core.amqp.implementation
  • com.azure.core.amqp.implementation.handler
    • A exceção é que você pode ignorar a onDelivery mensagem no ReceiveLinkHandler.
  • com.azure.messaging.servicebus.implementation

Simultaneidade em ProcessorClient

ProcessorClient Permite que o aplicativo configure quantas chamadas para o manipulador de mensagens devem acontecer simultaneamente. Esta configuração torna possível processar várias mensagens em paralelo. Para um ProcessorClient consumo de mensagens de uma entidade que não seja de sessão, o aplicativo pode configurar a simultaneidade desejada usando a maxConcurrentCalls API. Para uma entidade habilitada para sessão, a simultaneidade desejada é maxConcurrentSessions vezes maxConcurrentCalls.

Se o aplicativo observar menos chamadas simultâneas para o manipulador de mensagens do que a simultaneidade configurada, pode ser porque o pool de threads não é dimensionado adequadamente.

ProcessorClient usa threads de daemon do pool de threads global boundedElastic do Reator para invocar o manipulador de mensagens. O número máximo de threads simultâneos neste pool é limitado por um limite. Por padrão, esse limite é dez vezes o número de núcleos de CPU disponíveis. Para que o ProcessorClient suporte efetivamente a simultaneidade desejada do aplicativo (maxConcurrentCalls ou maxConcurrentSessions vezes maxConcurrentCalls), você deve ter um boundedElastic valor de limite de pool que seja maior do que a simultaneidade desejada. Você pode substituir o limite padrão definindo a propriedade reactor.schedulers.defaultBoundedElasticSizedo sistema .

Você deve ajustar o pool de threads e a alocação da CPU caso a caso. No entanto, quando você substituir a tampa do pool, como ponto de partida, limite os threads simultâneos para aproximadamente 20-30 por núcleo da CPU. Recomendamos que você limite a simultaneidade desejada por ProcessorClient instância para aproximadamente 20-30. Crie o perfil e meça seu caso de uso específico e ajuste os aspetos de simultaneidade de acordo. Para cenários de alta carga, considere a execução de várias ProcessorClient instâncias em que cada instância é criada a partir de uma nova ServiceBusClientBuilder instância. Além disso, considere executar cada ProcessorClient um em um host dedicado - como um contêiner ou VM - para que o tempo de inatividade em um host não afete o processamento geral de mensagens.

Lembre-se de que definir um valor alto para o limite de pool em um host com poucos núcleos de CPU teria efeitos adversos. Alguns sinais de baixos recursos de CPU ou um pool com muitos threads em menos CPUs são: tempos limite frequentes, bloqueio perdido, deadlock ou menor taxa de transferência. Se você estiver executando o aplicativo Java em um contêiner, recomendamos o uso de dois ou mais núcleos vCPU. Não recomendamos selecionar nada menos que 1 núcleo vCPU ao executar o aplicativo Java em ambientes conteinerizados. Para obter recomendações detalhadas sobre recursos, consulte Containerize your Java applications.

Atualize para 7.15.x ou mais recente

Se você encontrar algum problema, primeiro tente resolvê-lo atualizando para a versão mais recente do SDK do Service Bus. A versão 7.15.x é uma grande reformulação, resolvendo problemas de desempenho e confiabilidade de longa data.

A versão 7.15.x e posterior reduz o salto de threads, remove bloqueios, otimiza o código em caminhos quentes e reduz as alocações de memória. Essas alterações resultam em uma taxa de transferência até 45-50 vezes maior no ServiceBusProcessor cliente.

A versão 7.15.x e posterior também vem com várias melhorias de confiabilidade. Ele aborda várias condições de corrida (como pré-busca e cálculos de crédito) e melhorou o tratamento de erros. Essas alterações resultam em maior confiabilidade na presença de problemas transitórios em vários tipos de clientes.

Utilizar os clientes mais recentes

A nova estrutura subjacente com essas melhorias - na versão 7.15.x e posterior - é chamada de V2-Stack. Esta linha de lançamento inclui a geração anterior da pilha subjacente - a pilha que a versão 7.14.x usa - e a nova V2-Stack.

Por padrão, alguns dos tipos de cliente usam o V2-Stack, enquanto outros exigem o opt-in V2-Stack. Você pode realizar o opt-in ou opt-out de uma pilha específica (V2 ou a geração anterior) para um tipo de cliente fornecendo com.azure.core.util.Configuration valores quando você cria o cliente.

Por exemplo, a sessão baseada em V2-Stack recebe com ServiceBusSessionReceiverClient requer opt-in, conforme mostrado no exemplo a seguir:

ServiceBusSessionReceiverClient sessionReceiver = new ServiceBusClientBuilder()
    .connectionString(Config.CONNECTION_STRING)
    .configuration(new com.azure.core.util.ConfigurationBuilder()
        .putProperty("com.azure.messaging.servicebus.session.syncReceive.v2", "true") // 'false' by default, opt-in for V2-Stack.
        .build())
    .sessionReceiver()
    .queueName(Config.QUEUE_NAME)
    .buildClient();

A tabela a seguir lista os tipos de cliente e os nomes de configuração correspondentes e indica se o cliente está atualmente habilitado por padrão para usar o V2-Stack na versão mais recente 7.16.0. Para um cliente que não está na V2-Stack por padrão, você pode usar o exemplo mostrado para aceitar.

Tipo de cliente Nome da configuração Está no V2-Stack por padrão?
Remetente e cliente de gerenciamento com.azure.messaging.servicebus.sendAndManageRules.v2 sim
Cliente do recetor do reator e do processador que não é de sessão com.azure.messaging.servicebus.nonSession.asyncReceive.v2 sim
Cliente recetor do processador de sessão com.azure.messaging.servicebus.session.processor.asyncReceive.v2 sim
Cliente recetor do reator de sessão com.azure.messaging.servicebus.session.reactor.asyncReceive.v2 sim
Cliente recetor síncrono sem sessão com.azure.messaging.servicebus.nonSession.syncReceive.v2 não
Cliente recetor síncrono de sessão com.azure.messaging.servicebus.session.syncReceive.v2 não

Como alternativa ao uso com.azure.core.util.Configurationdo , você pode fazer o opt-in ou opt-out definindo os mesmos nomes de configuração usando variáveis de ambiente ou propriedades do sistema.

Próximos passos

Se as diretrizes de solução de problemas neste artigo não ajudarem a resolver problemas quando você usa o SDK do Azure para bibliotecas de cliente Java, recomendamos que você registre um problema no repositório do SDK do Azure para Java GitHub.