Partilhar via


Exceções de mensagens do Service Bus (.NET)

A biblioteca de cliente .NET do Service Bus apresenta exceções quando uma operação de serviço ou um cliente encontra um erro. Quando possível, os tipos de exceção .NET padrão são usados para transmitir informações de erro. Para cenários específicos do Service Bus, uma ServiceBusException é lançada.

Os clientes do Service Bus tentam automaticamente as exceções consideradas transitórias, seguindo as opções de repetição configuradas. Quando uma exceção é exibida ao aplicativo, todas as novas tentativas foram aplicadas sem êxito ou a exceção foi considerada não transitória. Mais informações sobre como configurar opções de repetição podem ser encontradas no Personalizando o exemplo de opções de repetição.

ServiceBusException

A exceção inclui algumas informações contextuais para ajudá-lo a entender o contexto do erro e sua gravidade relativa.

  • EntityPath : Identifica a entidade do Service Bus da qual a exceção ocorreu, se disponível.
  • IsTransient : Indica se a exceção é ou não considerada recuperável. No caso em que foi considerado transitório, o Barramento de Serviço do Azure já aplicou a política de repetição apropriada e todas as novas tentativas não tiveram êxito.
  • Message : Fornece uma descrição do erro que ocorreu e contexto relevante.
  • StackTrace : Representa os quadros imediatos da pilha de chamadas, destacando o local no código onde o erro ocorreu.
  • InnerException : Quando uma exceção é o resultado de uma operação de serviço, geralmente é uma Microsoft.Azure.Amqp.AmqpException instância que descreve o erro, seguindo a especificação do OASIS Advanced Message Queuing Protocol (AMQP) 1.0.
  • Reason : Fornece um conjunto de razões bem conhecidas para a falha que ajudam a categorizar e esclarecer a causa raiz. Esses valores destinam-se a permitir a aplicação de filtragem de exceção e outra lógica em que inspecionar o texto de uma mensagem de exceção não seria ideal. Alguns dos principais motivos de falha são:
    • ServiceTimeout: Indica que o serviço do Service Bus não respondeu a uma solicitação de operação dentro do tempo esperado. Pode ser devido a um problema transitório de rede ou problema de serviço. O serviço Service Bus pode ou não ter concluído a solicitação com êxito; o status não é conhecido. No contexto da próxima sessão disponível, essa exceção indica que não havia sessões desbloqueadas disponíveis na entidade. Esses erros são erros transitórios que são repetidos automaticamente.

    • QuotaExceeded: Normalmente indica que há muitas operações de recebimento ativas para uma única entidade. Para evitar esse erro, reduza o número de potenciais recebimentos simultâneos. Você pode usar recebimentos em lote para tentar receber várias mensagens por solicitação de recebimento. Para obter mais informações, consulte Cotas do Service Bus.

    • MessageSizeExceeded: Indica que o tamanho da mensagem excedeu o tamanho máximo da mensagem. O tamanho da mensagem inclui o corpo da mensagem e quaisquer metadados associados. A melhor abordagem para resolver esse erro é reduzir o número de mensagens enviadas em um lote ou o tamanho do corpo incluído na mensagem. Como os limites de tamanho estão sujeitos a alterações, consulte Cotas do Barramento de Serviço para obter informações específicas.

    • MessageLockLost: Indica que o bloqueio da mensagem foi perdido. Os chamadores devem tentar receber e processar a mensagem novamente. Esta exceção aplica-se apenas a entidades que não utilizam sessões. Este erro ocorre se o processamento demorar mais do que a duração do bloqueio e o bloqueio de mensagem não for renovado. Este erro também pode ocorrer quando o link é desanexado devido a um problema de rede transitório ou quando o link está ocioso por 10 minutos.

      O serviço Service Bus usa o protocolo AMQP, que é stateful. Devido à natureza do protocolo, se o link que conecta o cliente e o serviço for desanexado depois que uma mensagem for recebida, mas antes que a mensagem seja resolvida, a mensagem não poderá ser resolvida ao reconectar o link. Os links podem ser desanexados devido a uma falha de rede transitória de curto prazo, uma interrupção de rede ou devido ao tempo limite de ociosidade de 10 minutos imposto pelo serviço. A reconexão do link acontece automaticamente como parte de qualquer operação que exija o link, ou seja, resolver ou receber mensagens. Devido a esse comportamento, você pode se deparar ServiceBusException com Reason MessageLockLost ou SessionLockLost mesmo se o tempo de expiração do bloqueio ainda não tiver passado.

    • SessionLockLost: Indica que o bloqueio na sessão expirou. Os chamadores devem tentar aceitar a sessão novamente. Esta exceção aplica-se apenas a entidades habilitadas para sessão. Este erro ocorre se o processamento demorar mais do que a duração do bloqueio e o bloqueio de sessão não for renovado. Este erro também pode ocorrer quando o link é desanexado devido a um problema de rede transitório ou quando o link está ocioso por 10 minutos. O serviço Service Bus usa o protocolo AMQP, que é stateful. Devido à natureza do protocolo, se o link que conecta o cliente e o serviço for desanexado depois que uma mensagem for recebida, mas antes que a mensagem seja resolvida, a mensagem não poderá ser resolvida ao reconectar o link. Os links podem ser desanexados devido a uma falha de rede transitória de curto prazo, uma interrupção de rede ou devido ao tempo limite de ociosidade de 10 minutos imposto pelo serviço. A reconexão do link acontece automaticamente como parte de qualquer operação que exija o link, ou seja, resolver ou receber mensagens. Devido a esse comportamento, você pode se deparar ServiceBusException com Reason MessageLockLost ou SessionLockLost mesmo se o tempo de expiração do bloqueio ainda não tiver passado.

    • MessageNotFound: Este erro ocorre ao tentar receber uma mensagem adiada por número de sequência para uma mensagem que não existe na entidade ou está bloqueada no momento.

    • SessionCannotBeLocked: Indica que a sessão solicitada não pode ser bloqueada porque o bloqueio já está mantido em outro lugar. Quando o bloqueio expirar, a sessão pode ser aceite.

    • GeneralError: Indica que o serviço Service Bus encontrou um erro ao processar a solicitação. Esse erro geralmente é causado por atualizações e reinicializações de serviço. Esses erros são erros transitórios que são repetidos automaticamente.

    • ServiceCommunicationProblem: Indica que houve um erro na comunicação com o serviço. O problema pode decorrer de um problema transitório de rede ou de um problema de serviço. Esses erros são erros transitórios que serão repetidos automaticamente.

    • ServiceBusy: Indica que uma solicitação foi limitada pelo serviço. Os detalhes que descrevem o que pode fazer com que uma solicitação seja limitada e como evitar ser limitada podem ser encontrados aqui. As solicitações limitadas são repetidas, mas a biblioteca do cliente aplica automaticamente um recuo de 10 segundos antes de tentar mais solicitações usando o mesmo ServiceBusClient (ou quaisquer subtipos criados a partir desse cliente). Pode causar problemas se a duração do bloqueio da sua entidade for inferior a 10 segundos, uma vez que é provável que os bloqueios de mensagens ou sessões de sessão sejam perdidos para quaisquer mensagens não resolvidas ou sessões bloqueadas. Como as solicitações limitadas geralmente são repetidas com êxito, as exceções geradas seriam registradas como avisos em vez de erros - o evento de origem de evento de nível de aviso específico é 43 (RunOperation encontrou uma exceção e ocorre uma nova tentativa.).

    • MessagingEntityAlreadyExists: Indica que uma entidade com o mesmo nome existe sob o mesmo namespace.

    • MessagingEntityDisabled: A entidade de mensagens está desativada. Habilite a entidade novamente usando o Portal.

    • MessagingEntityNotFound: O serviço do Service Bus não consegue encontrar um recurso do Service Bus.

Handle ServiceBusException - exemplo

Aqui está um exemplo de como lidar com um ServiceBusException e filtrar pelo Reason.

try
{
    // Receive messages using the receiver client
}
catch (ServiceBusException ex) when
    (ex.Reason == ServiceBusFailureReason.ServiceTimeout)
{
    // Take action based on a service timeout
}

Outras exceções comuns

  • ArgumentException: O cliente lança essa exceção derivada de ArgumentException quando um parâmetro fornecido ao interagir com o cliente é inválido. Informações sobre o parâmetro específico e a natureza do problema podem ser encontradas no Message.
  • InvalidOperationException: Ocorre ao tentar executar uma operação que não é válida para sua configuração atual. Essa exceção normalmente ocorre quando um cliente não foi configurado para suportar a operação. Muitas vezes, pode ser atenuado ajustando as opções passadas para o cliente.
  • NotSupportedException: Ocorre quando uma operação solicitada é válida para o cliente, mas não é suportada pelo seu estado atual. Informações sobre o cenário podem ser encontradas no Message.
  • AggregateException: Ocorre quando uma operação pode encontrar várias exceções e as apresenta como uma única falha. Essa exceção é mais comumente encontrada ao iniciar ou parar o processador do Service Bus ou o processador de sessão do Service Bus.

Motivo: QuotaExcedieded

ServiceBusException com motivo definido como QuotaExceeded indica que uma cota para uma entidade específica foi excedida.

Nota

Para cotas do Service Bus, consulte Cotas.

Filas e tópicos

Para filas e tópicos, geralmente é o tamanho da fila. A propriedade error message contém mais detalhes, como no exemplo a seguir:

Message: The maximum entity size has been reached or exceeded for Topic: 'xxx-xxx-xxx'. 
    Size of entity in bytes:1073742326, Max entity size in bytes:
1073741824..TrackingId:xxxxxxxxxxxxxxxxxxxxxxxxxx, TimeStamp:3/15/2013 7:50:18 AM

A mensagem afirma que o tópico excedeu seu limite de tamanho, neste caso 1 GB (o limite de tamanho padrão).

Espaços de nomes

Para namespaces, a exceção QuotaExceeded pode indicar que um aplicativo excedeu o número máximo de conexões com um namespace. Por exemplo:

<tracking-id-guid>_G12 ---> 
System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: 
ConnectionsQuotaExceeded for namespace xxx.

Causas comuns

Há duas causas comuns para esse erro: a fila de mensagens mortas e os recetores de mensagens que não funcionam.

  • Fila de mensagens mortas Um leitor não está conseguindo concluir as mensagens e as mensagens são retornadas para a fila/tópico quando o bloqueio expira. Isso pode acontecer se o leitor encontrar uma exceção que o impeça de concluir a mensagem. Depois que uma mensagem for lida 10 vezes, ela será movida para a fila de mensagens mortas por padrão. Esse comportamento é controlado pela propriedade MaxDeliveryCount e tem um valor padrão de 10. À medida que as mensagens se acumulam na fila de letras mortas, elas ocupam espaço.

    Para resolver o problema, leia e conclua as mensagens da fila de mensagens mortas, como faria em qualquer outra fila.

  • O recetor parou. Um destinatário parou de receber mensagens de uma fila ou assinatura. A maneira de identificar o problema é olhar para a contagem de mensagens ativas. Se a contagem de mensagens ativas estiver alta ou crescendo, as mensagens não estão sendo lidas tão rápido quanto estão sendo escritas.

Motivo: MessageLockLost

Causa

ServiceBusException com motivo definido como MessageLockLost indica que uma mensagem é recebida usando o modo de recebimento PeekLock e o bloqueio mantido pelo cliente expira no lado do serviço.

O bloqueio de uma mensagem pode expirar devido a vários motivos:

  • O temporizador de bloqueio expirou antes de ser renovado pelo aplicativo cliente.
  • O aplicativo cliente adquiriu o bloqueio, salvou-o em um armazenamento persistente e, em seguida, reiniciado. Uma vez reiniciado, o aplicativo cliente olhou para as mensagens de bordo e tentou concluir as mensagens.

Você também pode receber essa exceção nos seguintes cenários:

  • Atualização do Serviço
  • Atualização do SO
  • Alterar propriedades na entidade (fila, tópico, assinatura) enquanto mantém o bloqueio.

Resolução

Quando um aplicativo cliente recebe MessageLockLostException, ele não pode mais processar a mensagem. O aplicativo cliente pode, opcionalmente, considerar registrar a exceção para análise, mas o cliente deve descartar a mensagem.

Como o bloqueio na mensagem expirou, ele voltaria para a Fila (ou Assinatura) e poderia ser processado pelo próximo aplicativo cliente que as chamadas recebessem.

Se o MaxDeliveryCount tiver excedido, a mensagem pode ser movida para o DeadLetterQueue.

Motivo: SessionLockLost

Causa

ServiceBusException com motivo definido como MessageLockLost é lançado quando uma sessão é aceita e o bloqueio mantido pelo cliente expira no lado do serviço.

O bloqueio de uma sessão pode expirar devido a vários motivos:

  • O temporizador de bloqueio expirou antes de ser renovado pelo aplicativo cliente.
  • O aplicativo cliente adquiriu o bloqueio, salvou-o em um armazenamento persistente e, em seguida, reiniciado. Depois de reiniciado, o aplicativo cliente olhou para as sessões de bordo e tentou processar as mensagens nessas sessões.

Você também pode receber essa exceção nos seguintes cenários:

  • Atualização do Serviço
  • Atualização do SO
  • Alterar propriedades na entidade (fila, tópico, assinatura) enquanto mantém o bloqueio.

Resolução

Quando um aplicativo cliente recebe SessionLockLostException, ele não pode mais processar as mensagens na sessão. O aplicativo cliente pode considerar registrar a exceção para análise, mas o cliente deve descartar a mensagem.

Como o bloqueio da sessão expirou, ele voltaria para a Fila (ou Assinatura) e poderia ser bloqueado pelo próximo aplicativo cliente que aceitasse a sessão. Como o bloqueio de sessão é mantido por um único aplicativo cliente a qualquer momento, o processamento em ordem é garantido.

TimeoutException

Uma TimeoutException indica que uma operação iniciada pelo utilizador está a demorar mais do que o tempo limite da operação.

Você deve verificar o valor da propriedade ServicePointManager.DefaultConnectionLimit , pois atingir esse limite também pode causar uma TimeoutException.

Espera-se que os tempos limite ocorram durante ou entre as operações de manutenção, como as atualizações de serviço do Service Bus (ou) atualizações do SO nos recursos que executam o serviço. Durante as atualizações de SO, as entidades são movidas e os nós são atualizados ou reiniciados, o que pode causar tempos limite. Para obter detalhes sobre o contrato de nível de serviço (SLA) para o serviço Azure Service Bus, veja SLA para o Service Bus.

SocketException

Causa

Um SocketException é lançado nos seguintes casos:

  • Quando uma tentativa de conexão falha porque o host não respondeu corretamente após um tempo especificado (código de erro TCP 10060).
  • Uma conexão estabelecida falhou porque o host conectado não respondeu.
  • Ocorreu um erro ao processar a mensagem ou o tempo limite é excedido pelo anfitrião remoto.
  • Problema subjacente de recursos de rede.

Resolução

Os erros SocketException indicam que a VM que hospeda os aplicativos não consegue converter o nome <mynamespace>.servicebus.windows.net para o endereço IP correspondente.

Verifique se o comando a seguir consegue mapear para um endereço IP.

PS C:\> nslookup <mynamespace>.servicebus.windows.net

O que deve fornecer uma saída como:

Name:    <cloudappinstance>.cloudapp.net
Address:  XX.XX.XXX.240
Aliases:  <mynamespace>.servicebus.windows.net

Se o nome acima não resolver para um IP e o alias de namespace, verifique com o administrador da rede para investigar mais. A resolução de nomes é feita através de um servidor DNS, normalmente um recurso na rede do cliente. Se a resolução de DNS for feita pelo DNS do Azure, entre em contato com o suporte do Azure.

Se a resolução de nomes funcionar conforme o esperado, verifique se as conexões com o Barramento de Serviço do Azure são permitidas aqui.

UnauthorizedAccessException

Uma UnauthorizedAccessException indica que as credenciais fornecidas não permitem que a ação solicitada seja executada. A Message propriedade contém detalhes sobre a falha.

Recomendamos que você siga estas etapas de verificação, dependendo do tipo de autorização fornecida ao construir o ServiceBusClient.

Exceções de replicação geográfica

ServerBusyException

Causas

  • Durante a replicação assíncrona (atraso de replicação maior que zero), o cliente tenta executar uma operação em uma entidade do Service Bus (fila, tópico) ou executa uma operação de gerenciamento, mas a operação não pode ser concluída porque o atraso de replicação entre as regiões primária e secundária excedeu o atraso máximo de replicação permitido em segundos.
    • Exemplo: A operação está sendo limitada porque, com ela, o novo atraso de replicação chegaria a 38.323 segundos, o que é maior do que o atraso máximo de replicação definido (300 segundos). O atraso de replicação atual para a operação mais recente que está sendo replicada é de 0 segundos.
  • A fila de replicação de uma entidade excede seu tamanho máximo em bytes. O tamanho máximo em bytes para uma fila de replicação é um limite interno definido pelo Service Bus.
    • Exemplo: O tamanho da fila de replicação 73128000 excedeu o limite 67108864.
  • Na replicação síncrona, uma solicitação atinge o tempo limite enquanto aguarda a replicação de outra solicitação.
    • Exemplo: Alto volume de solicitações do aplicativo cliente para skarri-storage-exp1(westus3)/q1:MessagingJournal. A replicação para outras regiões está em andamento.

Resolução

  • O cliente deve recuar para dar tempo para o serviço processar sua carga de trabalho dada, então o cliente deve tentar novamente.

Limite de tempo excedido

Causa

  • Uma exceção de tempo limite no Geo DR significa que a operação não foi concluída dentro do tempo limite fornecido pelo cliente.
    • Na replicação síncrona, a gravação da região primária de uma operação e a replicação para regiões secundárias estão dentro do escopo do tempo limite da operação.
    • Na replicação assíncrona, a gravação da região primária de uma operação está dentro do escopo do tempo limite da operação, mas a replicação de uma operação para regiões secundárias não está dentro do escopo do tempo limite da operação.
    • Exemplo: A operação não foi concluída dentro do tempo alocado 00:01:00 para a mensagem do objeto. (ServiceTimeout).

Resolução

  • O cliente deve repetir a operação.
  • Algumas etapas de uma operação com tempo limite expirado podem ter sido concluídas. É possível que uma operação com tempo limite limite tenha sido gravada na região primária e em algumas regiões secundárias. Se uma operação tiver sido gravada na região primária, ela acabará sendo replicada para todas as regiões secundárias, independentemente do tempo limite do cliente.

BadRequest

Causa

  • Durante um failover planejado, a região primária é temporariamente definida como somente leitura para permitir que a região secundária recupere. Se o cliente tentar uma operação de gravação na região primária enquanto estiver nesse estado somente leitura temporário, o cliente receberá uma exceção BadRequest.
    • Exemplo: Opção de função de replicação em andamento, réplica primária:<entity-name> é ReadOnly.

Resolução

  • O cliente deve aguardar a conclusão do failover planejado antes que as operações de gravação sejam bem-sucedidas.
  • Caso o failover planejado demore muito, é possível acionar um failover forçado.

Próximos passos

Para obter a referência completa da API .NET do Service Bus, consulte a referência da API do Azure .NET. Para obter dicas de solução de problemas, consulte o Guia de solução de problemas.