Solucionar problemas do processador de eventos dos Hubs de Eventos do Azure
Este artigo fornece soluções para problemas comuns que você pode encontrar ao usar o EventProcessorClient
tipo. Se você estiver procurando soluções para outros problemas comuns que pode encontrar ao usar os Hubs de Eventos do Azure, consulte Solucionar problemas dos Hubs de Eventos do Azure.
412 falhas de pré-condição ao usar um processador de eventos
412 Erros de pré-condição ocorrem quando o cliente tenta assumir ou renovar a propriedade de uma partição, mas a versão local do registro de propriedade está desatualizada. Esse problema ocorre quando outra instância do processador rouba a propriedade da partição. Para obter mais informações, consulte a próxima seção.
A propriedade da partição muda com frequência
Quando o número de EventProcessorClient
instâncias é alterado (ou seja, são adicionadas ou removidas), as instâncias em execução tentam balancear a carga das partições entre si. Por alguns minutos após as mudanças no número de processadores, espera-se que as partições mudem de proprietário. Depois de balanceada, a propriedade da partição deve ser estável e mudar com pouca frequência. Se a propriedade da partição estiver mudando com frequência quando o número de processadores é constante, isso provavelmente indica um problema. Recomendamos que você registre um problema no GitHub com logs e uma reprodução.
A propriedade da partição é determinada por meio dos registros de propriedade no CheckpointStore
. Em cada intervalo de balanceamento de carga, o EventProcessorClient
executará as seguintes tarefas:
- Busque os registros de propriedade mais recentes.
- Verifique os registros para ver quais registros não atualizaram seu carimbo de data/hora dentro do intervalo de expiração de propriedade da partição. Somente registros que correspondem a esses critérios são considerados.
- Se houver partições sem propriedade e a carga não estiver balanceada entre instâncias do , o cliente do processador de
EventProcessorClient
eventos tentará reivindicar uma partição. - Atualize o registro de propriedade para as partições que ele possui que têm um link ativo para essa partição.
Você pode configurar os intervalos de expiração de propriedade e balanceamento de carga ao criar o EventProcessorClient
, EventProcessorClientBuilder
conforme descrito na lista a seguir:
- O método loadBalancingUpdateInterval(Duration) indica com que frequência o ciclo de balanceamento de carga é executado.
- O método partitionOwnershipExpirationInterval(Duration) indica a quantidade mínima de tempo desde que o registro de propriedade foi atualizado, antes que o processador considere uma partição sem dono.
Por exemplo, se um registro de propriedade foi atualizado às 9h30 e partitionOwnershipExpirationInterval
tem 2 minutos. Quando um ciclo de balanceamento de carga ocorre e ele percebe que o registro de propriedade não foi atualizado nos últimos 2 min ou até as 9h32, ele considerará a partição sem dono.
Se ocorrer um erro em um dos consumidores de partição, ele fechará o consumidor correspondente, mas não tentará recuperá-lo até o próximo ciclo de balanceamento de carga.
"... receptor atual 'RECEIVER_NAME>' com época '0'< está sendo desconectado"
A mensagem de erro inteira é semelhante à seguinte saída:
New receiver 'nil' with higher epoch of '0' is created hence current receiver 'nil' with epoch '0'
is getting disconnected. If you are recreating the receiver, make sure a higher epoch is used.
TrackingId:<GUID>, SystemTracker:<NAMESPACE>:eventhub:<EVENT_HUB_NAME>|<CONSUMER_GROUP>,
Timestamp:2022-01-01T12:00:00}"}
Esse erro é esperado quando o balanceamento de carga ocorre depois que EventProcessorClient
as instâncias são adicionadas ou removidas. O balanceamento de carga é um processo contínuo. Quando você usa o com seu consumidor, a cada ~30 segundos (por padrão), o BlobCheckpointStore
consumidor verifica para ver quais consumidores têm uma reivindicação para cada partição e, em seguida, executa alguma lógica para determinar se ele precisa "roubar" uma partição de outro consumidor. O mecanismo de serviço usado para afirmar a propriedade exclusiva sobre uma partição é conhecido como Epoch.
No entanto, se nenhuma instância estiver sendo adicionada ou removida, há um problema subjacente que deve ser resolvido. Para obter mais informações, consulte a seção Alterações de propriedade de partição com frequência e Problemas de arquivamento do GitHub.
Alto uso da CPU
O alto uso da CPU geralmente ocorre porque uma instância possui muitas partições. Recomendamos não mais do que três partições para cada núcleo de CPU. É melhor começar com partições 1.5 para cada núcleo de CPU e, em seguida, testar aumentando o número de partições possuídas.
Sem memória e escolhendo o tamanho do heap
O problema de falta de memória (OOM) pode acontecer se o heap máximo atual para a JVM for insuficiente para executar o aplicativo. Talvez você queira medir o requisito de heap do aplicativo. Em seguida, com base no resultado, dimensione o heap definindo a memória de heap máxima apropriada usando a -Xmx
opção JVM.
Você não deve especificar -Xmx
como um valor maior do que a memória disponível ou o limite definido para o host (a VM ou o contêiner) - por exemplo, a memória solicitada na configuração do contêiner. Você deve alocar memória suficiente para que o host suporte o heap Java.
As etapas a seguir descrevem uma maneira típica de medir o valor de max Java Heap:
Execute o aplicativo em um ambiente próximo à produção, onde o aplicativo envia, recebe e processa eventos sob a carga de pico esperada na produção.
Aguarde até que o aplicativo atinja um estado estacionário. Neste estágio, o aplicativo e a JVM teriam carregado todos os objetos de domínio, tipos de classe, instâncias estáticas, pools de objetos (TCP, pools de conexões de banco de dados), etc.
Sob o estado estável, você vê o padrão estável em forma de dente de serra para a coleção de heap, conforme mostrado na captura de tela a seguir:
Depois que o aplicativo atingir o estado estacionário, force uma coleta de lixo completa (GC) usando ferramentas como JConsole. Observe a memória ocupada após o CG completo. Você deseja dimensionar o heap de forma que apenas 30% seja ocupado após o GC completo. Você pode usar esse valor para definir o tamanho máximo do heap (usando
-Xmx
).
Se você estiver no contêiner, dimensione o contêiner para ter ~1 GB extra de memória para a necessidade de não heap para a instância da JVM.
O cliente do processador pára de receber
O cliente do processador geralmente é executado continuamente em um aplicativo host por dias a fio. Às vezes, ele percebe que EventProcessorClient
não está processando uma ou mais partições. Normalmente, não há informações suficientes para determinar por que a exceção ocorreu. A EventProcessorClient
parada é o sintoma de uma causa subjacente (ou seja, a condição de corrida) que ocorreu ao tentar se recuperar de um erro transitório. Para obter as informações necessárias, consulte Arquivando problemas do GitHub.
Duplicar EventData recebido quando o processador é reiniciado
O EventProcessorClient
serviço e Hubs de Eventos garante uma entrega pelo menos uma vez . Você pode adicionar metadados para discernir eventos duplicados. Para obter mais informações, consulte Os Hubs de Eventos do Azure garantem uma entrega pelo menos uma vez? em Estouro de pilha. Se você precisar de entrega apenas uma vez, você deve considerar o Service Bus, que aguarda uma confirmação do cliente. Para obter uma comparação dos serviços de mensagens, consulte Escolhendo entre os serviços de mensagens do Azure.
Migrar da biblioteca herdada para a nova biblioteca do cliente
O guia de migração inclui etapas sobre a migração do cliente herdado e a migração de pontos de verificação herdados.
Próximas etapas
Se a orientação de solução de problemas neste artigo não ajudar a resolver problemas ao usar o SDK do Azure para bibliotecas de cliente Java, recomendamos que você registre um problema no repositório do Azure SDK para Java GitHub.