Compartilhar via


Diagnosticar e solucionar problemas de exceção de tempo limite de solicitação do SDK do .NET do Azure Cosmos DB

APLICA-SE A: NoSQL

O erro HTTP 408 ocorre quando o SDK não consegue completar a solicitação antes de atingir tempo limite.

É importante garantir que o design do aplicativo esteja de acordo com nosso guia para criar aplicativos resilientes com SDKs do Azure Cosmos DB, para garantir que ele reaja corretamente a diferentes condições de rede. Seu aplicativo deve ter novas tentativas em vigor para erros de tempo limite, pois normalmente são esperados em um sistema distribuído.

Ao avaliar o caso de erros de tempo limite excedido:

  • Qual é o impacto medido no volume de operações afetadas, em comparação às operações bem-sucedidas? Está nos SLAs de serviço?
  • A latência e a disponibilidade P99 são afetadas?
  • As falhas estão afetando todas as instâncias de aplicativo ou apenas um subconjunto? Quando o problema é reduzido a um subconjunto de instâncias, normalmente é um problema relacionado a essas instâncias.

Personalizar o tempo limite no SDK do .NET do Azure Cosmos DB

O SDK tem duas alternativas distintas para controlar os tempos limite, cada uma com um escopo diferente.

Tempos limite do nível de solicitação

A configuração CosmosClientOptions.RequestTimeout (ou ConnectionPolicy.RequestTimeout para o SDK v2) permite definir um tempo limite para a solicitação de rede após a solicitação deixar o SDK e estar na rede, até que uma resposta seja recebida.

A configuração CosmosClientOptions.OpenTcpConnectionTimeout (ou ConnectionPolicy.OpenTcpConnectionTimeout para o SDK v2) permite que você defina um tempo limite para o tempo gasto abrindo uma conexão inicial. Depois que uma conexão é aberta, as solicitações subsequentes usarão a conexão.

Uma operação iniciada por um usuário pode abranger várias solicitações de rede, por exemplo, novas tentativas. Essas duas configurações são por solicitação, não de ponta a ponta para uma operação.

CancellationToken

Todas as operações assíncronas no SDK têm um parâmetro CancellationToken opcional. Esse parâmetro CancellationToken é usado em toda a operação, em todas as solicitações e em novas tentativas de rede. Entre as solicitações de rede, o token de cancelamento poderá estar marcado e uma operação poderá ser cancelada se o token relacionado tiver expirado. O token de cancelamento deve ser usado para definir um tempo limite aproximado esperado no escopo da operação.

Observação

O parâmetro CancellationToken é um mecanismo em que a biblioteca verificará o cancelamento quando não causar um estado inválido. A operação pode não ser cancelada exatamente quando o tempo definido no cancelamento estiver ativo. Em vez disso, depois que o tempo for ativado, ele cancelará quando for seguro fazer isso.

Etapas para solucionar problemas

A lista a seguir contém causas conhecidas e soluções para exceções de tempo limite de solicitação.

CosmosOperationCanceledException

Este tipo de exceção é comum quando o aplicativo está transmitindo CancellationTokens para as operações do SDK. O SDK verifica o estado de CancellationToken entre as tentativas e, caso CancellationToken seja cancelado, anula a operação atual com a exceção a seguir.

O Message / ToString() da exceção também indica o estado de CancellationToken por meio de Cancellation Token has expired: true e contém diagnósticos com o contexto do cancelamento para as solicitações envolvidas.

É seguro tentar realizar a operação novamente no caso dessas exceções e elas podem ser tratadas como tempos limite da perspectiva da repetição.

Solução

Verifique o tempo configurado no CancellationToken e se ele é maior que o RequestTimeout e o CosmosClientOptions.OpenTcpConnectionTimeout (se você estiver usando o modo direto). Se o tempo disponível em CancellationToken for menor do que o tempo limite configurado e o SDK estiver enfrentando problemas temporários de conectividade, o SDK não poderá tentar realizar novamente a operação e lançará CosmosOperationCanceledException.

Alta utilização da CPU

A alta utilização da CPU é o caso mais comum. Para ter uma latência ideal, o uso da CPU deve ser de aproximadamente 40%. Use 10 segundos como o intervalo para monitorar a utilização máxima (não média) da CPU. Picos de CPU são mais comuns com consultas entre partições, em que pode haver várias conexões para uma mesma consulta.

Os tempos limite conterão Diagnósticos, que incluem:

"systemHistory": [
{
"dateUtc": "2021-11-17T23:38:28.3115496Z",
"cpu": 16.731,
"memory": 9024120.000,
"threadInfo": {
"isThreadStarving": "False",
....
}

},
{
"dateUtc": "2021-11-17T23:38:28.3115496Z",
"cpu": 16.731,
"memory": 9024120.000,
"threadInfo": {
"isThreadStarving": "False",
....
}

},
...
]
  • Se os valores cpu estão acima de 70%, é provável que o tempo limite seja causado pelo esgotamento da CPU. Nesse caso, a solução é investigar a origem da alta utilização da CPU e reduzi-la, ou dimensionar a máquina para um tamanho de recurso maior.
  • Se os nós threadInfo/isThreadStarving têm valores True, a causa é a privação de threads. Nesse caso, a solução é investigar as origens da privação de thread (threads potencialmente bloqueados) ou dimensionar as máquinas para um tamanho de recurso maior.
  • Se o tempo de dateUtc entre as medições não for de cerca de dez segundos, isso também indicará contenção no pool de threads. A CPU é medida como uma tarefa independente que é enfileirada no pool de threads a cada dez segundos. Se o tempo entre as medições for maior, as tarefas assíncronas não poderão ser processadas em tempo hábil. Os cenários mais comuns ocorrem ao fazer o bloqueio de chamadas por código assíncrono no código do aplicativo.

Solução

O aplicativo cliente que usa o SDK deve ser expandido ou escalado verticalmente.

A disponibilidade do soquete ou da porta pode estar baixa

Ao executar no Azure, os clientes que usam o SDK do .NET podem atingir o esgotamento de porta de SNAT do Azure (PAT).

Solução 1

Se você está executando em VMs do Azure, siga o Guia de esgotamento da porta SNAT.

Solução 2

Se você estiver executando o Serviço de Aplicativo do Azure, siga o guia de solução de problemas de conexão e use o diagnóstico do Serviço de Aplicativo.

Solução 3

Se você está executando o Azure Functions, verifique se está seguindo a recomendação do Azure Functions de manter clientes singleton ou estáticos para todos os serviços envolvidos (incluindo o Azure Cosmos DB). Verifique os limites de serviço com base no tipo e no tamanho de sua hospedagem do Aplicativo de Funções.

Solução 4

Se você usar um proxy HTTP, certifique-se que pode suportar o número de conexões configuradas no SDK ConnectionPolicy. Caso contrário, você terá problemas de conexão.

Criar várias instâncias de cliente

A criação de várias instâncias de cliente pode levar à contenção de conexão e a problemas de tempo limite. O Diagnóstico contém duas propriedades relevantes:

{
    "NumberOfClientsCreated":X,
    "NumberOfActiveClients":Y,
}

NumberOfClientsCreated rastreia o número de vezes que um CosmosClient foi criado no mesmo AppDomain e NumberOfActiveClients rastreia os clientes ativos (não descartados). A expectativa é que, se o padrão singleton for seguido, X corresponderá ao número de contas com as quais o aplicativo funciona e que X será igual a Y.

Se X for maior que Y, significa que o aplicativo está criando e descartando instâncias de cliente. Isso pode levar à contenção de conexão e/ou à contenção da CPU.

Solução

Siga as dicas de desempenho e use uma única instância do CosmosClient por conta em todo o processo. Evite criar e descartar clientes.

Chave de partição ativa

O Azure Cosmos DB distribui a taxa de transferência provisionada geral de maneira uniforme entre as partições físicas. Quando há uma partição quente, uma ou mais chaves de partição lógica em uma partição física estão consumindo todas as RUs/s (unidades de solicitação por segundo) da partição física. Ao mesmo tempo, as RUs/s em outras partições físicas não são utilizadas. Como sintoma, o total de RUs/s consumidas será menor do que as RUs/s provisionadas no banco de dados ou contêiner, mas você ainda terá limitação (429s) das solicitações em relação à chave de partição lógica quente. Use a Métrica de consumo de RU normalizada para ver se a carga de trabalho está encontrando uma partição quente.

Solução

Escolha uma boa chave de partição que distribua de maneira uniforme o volume de solicitação e o armazenamento. Saiba como alterar a chave de partição.

Alto grau de simultaneidade

O aplicativo está criando um alto nível de simultaneidade, o que pode levar à contenção no canal.

Solução

O aplicativo cliente que usa o SDK deve ser expandido ou escalado verticalmente.

Solicitações ou respostas grandes

Solicitações ou respostas grandes podem levar ao bloqueio de início de linha no canal e exacerbar a contenção, mesmo com um grau relativamente baixo de simultaneidade.

Solução

O aplicativo cliente que usa o SDK deve ser expandido ou escalado verticalmente.

A taxa de falha está dentro do SLA do Azure Cosmos DB

O aplicativo deve ser capaz de lidar com falhas transitórias e tentar novamente quando necessário. Exceções 408 não são repetidas porque, ao criar caminhos, é impossível saber se o serviço criou o item ou não. Enviar o mesmo item novamente para criação causará uma exceção de conflito. A lógica de negócios dos aplicativos do usuário pode ter uma lógica personalizada para lidar com conflitos, o que eliminaria a ambiguidade de um item existente versus um conflito de repetição de criação.

A taxa de falha viola o SLA do Azure Cosmos DB

Entre em contato com o Suporte do Azure.

Próximas etapas