Compartilhar via


Exceções de mensagens do Barramento de Serviço (.NET)

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

Os clientes do Barramento de Serviço repetem automaticamente exceções consideradas transitórias, seguindo as opções de repetição configuradas. Quando uma exceção é apresentada no aplicativo, isso indica que todas as novas tentativas foram aplicadas sem êxito ou que a exceção foi considerada não transitória. É possível encontrar mais informações sobre como configurar opções de repetição na amostra Personalizar as opções de repetição.

ServiceBusException

A exceção inclui algumas informações contextuais para ajudar você a entender o contexto do erro e sua gravidade relativa.

  • EntityPath: identifica a entidade do Barramento de Serviço na qual ocorreu a exceção, se disponível.
  • IsTransient: indica se a exceção é ou não considerada recuperável. Caso ela tenha sido considerada transitória, o Barramento de Serviço do Azure já aplicou a política de repetição apropriada, e as repetições falharam.
  • Message: fornece uma descrição do erro ocorrido e do contexto relevante.
  • StackTrace: representa os quadros imediatos da pilha de chamadas, realçando a parte do código em que o erro ocorreu.
  • InnerException: quando o resultado de uma operação de serviço tiver sido uma exceção, geralmente é uma instância Microsoft.Azure.Amqp.AmqpException que descreve o erro, seguindo a especificação AMQP (Advanced Message Queuing Protocol) 1.0 do OASIS.
  • Reason: fornece um conjunto de motivos conhecidos 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 ao inspecionar o texto de uma mensagem de exceção que não seria ideal. Alguns motivos de falha de chave são:
    • ServiceTimeout: indica que o serviço do Barramento de Serviço não respondeu a uma solicitação de operação dentro do período de tempo esperado. Isso pode ser devido a um problema transitório de rede ou de serviço. O serviço do Barramento de Serviço 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 se repetem 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 possíveis recebimentos simultâneos. Você pode usar os recebimentos em lote para tentar receber várias mensagens por solicitação de recebimento. Para obter mais informações, confira Cotas do Barramento de Serviço.

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

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

      O serviço de Barramento de Serviço usa o protocolo AMQP, que conta com estado. 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 de ela ser estabelecida, ela não poderá ser estabelecida 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 ocioso de 10 minutos imposto pelo serviço. A reconexão do link ocorre automaticamente como parte de qualquer operação que exija o link, ou seja, o estabelecimento ou recebimento de mensagens. Devido a esse comportamento, você poderá encontrar ServiceBusException com Reason de 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. Essa exceção só se aplica a entidades habilitadas para sessão. Esse erro ocorrerá se o processamento demorar mais do que a duração do bloqueio e se o bloqueio da sessão não for renovado. Esse erro também pode ocorrer quando o link for desanexado devido a um problema de rede transitório ou quando o link ficar ocioso por 10 minutos. O serviço de Barramento de Serviço usa o protocolo AMQP, que conta com estado. 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 de ela ser estabelecida, ela não poderá ser estabelecida 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 ocioso de 10 minutos imposto pelo serviço. A reconexão do link ocorre automaticamente como parte de qualquer operação que exija o link, ou seja, o estabelecimento ou recebimento de mensagens. Devido a esse comportamento, você poderá encontrar ServiceBusException com Reason de MessageLockLost ou SessionLockLost mesmo se o tempo de expiração do bloqueio ainda não tiver passado.

    • MessageNotFound: esse erro ocorre ao tentar receber uma mensagem adiada devido ao número de sequência de 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á existe em outro lugar. Depois que o bloqueio expirar, a sessão poderá ser aceita.

    • GeneralError: indica que o serviço do Barramento de Serviço encontrou um erro ao processar a solicitação. Esse erro geralmente é causado por atualizações de serviço e reinicializações. Esses erros são erros transitórios que se repetem automaticamente.

    • ServiceCommunicationProblem: indica que houve um erro ao se comunicar com o serviço. O problema pode decorrer de um problema de rede transitório 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 levar uma solicitação a ser limitada e como evitar isso podem ser encontrados aqui. As solicitações limitadas são repetidas, mas a biblioteca de clientes aplica automaticamente um recuo de 10 segundos antes de tentar qualquer outra solicitação usando o mesmo ServiceBusClient (ou quaisquer subtipos criados a partir desse cliente). Isso poderá causar problemas se a duração do bloqueio da entidade for inferior a 10 segundos, já que os bloqueios de mensagem ou sessão provavelmente serão perdidos para mensagens não estabelecida 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 no nível de aviso específico é 43 (RunOperation encontrou uma exceção e ocorre a repetição).

    • MessagingEntityAlreadyExists: indica que existe uma entidade com o mesmo nome no mesmo namespace.

    • MessagingEntityDisabled: a Entidade de Mensagens está desabilitada. Habilite a entidade novamente usando o Portal.

    • MessagingEntityNotFound: o serviço do Barramento de Serviço não consegue encontrar um recurso do Barramento de Serviço.

Lidar com ServiceBusException – exemplo

Aqui está um exemplo de como lidar com uma ServiceBusException e filtrar por 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 gerará essa exceção derivada de ArgumentException quando um parâmetro fornecido ao interagir com o cliente for inválido. É possível encontrar informações sobre o parâmetro específico e a natureza do problema na 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 dar suporte à operação. Muitas vezes, ela pode ser atenuada ajustando as opções passadas para o cliente.
  • NotSupportedException: ocorre quando uma operação solicitada é válida para o cliente, mas não tem suporte pelo estado atual. É possível encontrar informações sobre o cenário na Message.
  • AggregateException: ocorre quando é possível que uma operação encontre várias exceções e esteja apresentando-as como uma única falha. Essa exceção é mais comumente encontrada ao iniciar ou parar o processador do Barramento de Serviço ou o processador de sessão do Barramento de Serviço.

Motivo: QuotaExceeded

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

Observação

Para cotas do Barramento de Serviço, consulte Cotas.

Filas e tópicos

Para filas e tópicos, isso geralmente é o tamanho da fila. A propriedade de mensagem de erro 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 informa que o tópico excedeu seu limite de tamanho, neste caso 1 GB (o limite de tamanho padrão).

Namespaces

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 desse erro: a fila de mensagens mortas e os destinatários de mensagem não estão funcionando.

  • Fila de mensagens mortas Um leitor não pode concluir as mensagens e as mensagens são retornadas para 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 foi lida 10 vezes, ela é movida para a fila de mensagens mortas por padrão. Esse comportamento é controlado pela propriedade MaxDeliveryCount e tem um valor padrão de 10. Conforme as mensagens são acumuladas na fila de mensagens 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.

  • Receptor parado. Um receptor parou de receber mensagens de uma fila ou assinatura. A maneira de identificar o problema é examinar a contagem de mensagens ativas. Se a contagem de mensagens ativas for alta ou crescente, as mensagens não serão lidas tão rapidamente quanto são escritas.

Motivo: MessageLockLost

Causa

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

O bloqueio em 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 repositório persistente e, em seguida, reiniciou. Após a reinicialização, o aplicativo cliente examinou as mensagens em andamento e tentou concluí-las.

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

  • Atualização de serviço
  • Atualização do SO
  • Alterando 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 o registro em log da exceção para análise, mas o cliente precisa descartar a mensagem.

Como o bloqueio na mensagem expirou, ela volta para a Fila (ou Assinatura) e pode ser processada pelo próximo aplicativo cliente que chamar o recebimento.

Se MaxDeliveryCount for excedida, a mensagem poderá ser movida para a DeadLetterQueue.

Motivo: SessionLockLost

Causa

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

O bloqueio em 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 repositório persistente e, em seguida, reiniciou. Depois de reiniciado, o aplicativo cliente examinou as sessões em andamento e tentou processar as mensagens nessas sessões.

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

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

Resolução

Quando um aplicativo cliente recebe uma SessionLockLostException, ele não pode mais processar as mensagens na sessão. O aplicativo cliente pode considerar o registro em log da exceção para análise, mas o cliente precisa descartar a mensagem.

Como o bloqueio na mensagem expirou, ela volta para a fila (ou assinatura) e pode ser bloqueada pelo próximo aplicativo cliente que aceita a sessão. Como o bloqueio de sessão é mantido por um único aplicativo cliente em um determinado momento, o processamento em ordem é garantido.

TimeoutException

Um TimeoutException indica que uma operação iniciada pelo usuário está demorando 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 um TimeoutException.

Espera-se que os tempos limite ocorram durante ou entre operações de manutenção, como atualizações de serviço do Barramento de Serviço (ou) atualizações de sistema operacional em recursos que executam o serviço. Durante as atualizações de sistema operacional, as entidades são movidas e os nós são atualizados ou reinicializados, o que pode fazê-los atingir o tempo limite. Para obter detalhes de SLA (Contrato de Nível de Serviço) para o serviço de Barramento de Serviço do Azure, confira SLA para Barramento de Serviço.

SocketException

Causa

Uma SocketException é lançada nos seguintes casos:

  • Em caso de falha de uma tentativa de conexão porque o host não respondeu corretamente após uma hora especificada (código de erro TCP 10060).
  • Uma conexão estabelecida falhou porque o host conectado falhou ao responder.
  • Ocorreu um erro ao processar a mensagem ou o tempo limite foi excedido pelo host remoto.
  • Problema de recurso de rede subjacente.

Resolução

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

Verifique se o comando a seguir tem êxito no mapeamento para um endereço IP.

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

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 for resolvido para um IP e o alias de namespace, entre em contato com o administrador da rede para uma investigação mais detalhada. A resolução de nomes é feita por meio de um servidor DNS que 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 aqui se as conexões com o Barramento de Serviço do Azure são permitidas.

UnauthorizedAccessException

Um UnauthorizedAccessException indica que as credenciais fornecidas não permitem que a ação solicitada seja executada. A propriedade Message 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 geográficas

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 barramento de serviço (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 retardo 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 Barramento de Serviço.
    • 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 outra solicitação ser replicada.
    • 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.

Solução

  • O cliente deve recuar para dar tempo ao serviço de processar a carga de trabalho fornecida e, em seguida, deve tentar novamente.

Timeout

Causa

  • Uma exceção de tempo limite na DR geográfica 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 na região primária de uma operação e a replicação em 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 de tempo limite podem ter sido concluídas. É possível que uma operação de tempo 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 eventualmente será replicada em todas as regiões secundárias, independentemente do tempo limite do cliente.

BadRequest

Causa

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

Solução

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

Próximas etapas

Para obter a referência completa da API do .NET de Barramento de Serviço, consulte a Referência de API do .NET do Azure. Para ver dicas de solução de problemas, confira o Guia de solução de problemas.