Esta página descreve o modelo de nova tentativa usado pelas bibliotecas de cliente C++.
As bibliotecas de cliente emitem RPCs (chamadas de procedimento remoto) em seu nome. Essas RPCs podem falhar devido a erros temporários. Os servidores são reiniciados, os balanceadores de carga fecham conexões ociosas ou sobrecarregadas, e os limites de taxa podem entrar em vigor. Esses são apenas alguns exemplos de falhas temporárias.
As bibliotecas podem retornar esses erros ao aplicativo. No entanto, muitos desses erros são fáceis de processar na biblioteca, o que simplifica o código do aplicativo.
Erros e operações que permitem novas tentativas
Só é possível repetir erros transitórios. Por exemplo, kUnavailable indica que o cliente não conseguiu se conectar ou perdeu a conexão com um serviço enquanto uma solicitação estava em andamento. Quase sempre, essa é uma condição temporária, mas pode levar muito tempo para se recuperar. Esses erros sempre podem ser repetidos, desde que a operação em si seja segura para isso. Por outro lado, os erros kPermissionDenied exigem intervenção adicional (geralmente humana) para serem resolvidos. Esses erros não são considerados "temporários", ou pelo menos não nas escalas de tempo consideradas pelos loops de repetição na biblioteca de cliente.
Da mesma forma, algumas operações não são seguras para novas tentativas, independente da natureza do erro. Isso inclui operações que fazem mudanças incrementais. Por exemplo, não é seguro tentar novamente uma operação para remover "a versão mais recente de X" quando pode haver várias versões de um recurso chamado "X". Isso acontece porque o chamador provavelmente queria remover uma única versão, e tentar de novo uma solicitação pode resultar na remoção de todas as versões.
Configurar loops de novas tentativas
As bibliotecas de cliente aceitam três parâmetros de configuração diferentes para controlar os loops de repetição:
- O
*IdempotencyPolicydetermina se uma solicitação específica é idempotente. Somente essas solicitações são repetidas. - O
*RetryPolicydetermina (a) se um erro deve ser considerado uma falha temporária e (b) por quanto tempo (ou quantas vezes) a biblioteca de cliente tenta novamente uma solicitação. - O
*BackoffPolicydetermina quanto tempo a biblioteca de cliente aguarda antes de reenviar a solicitação.
Política de idempotência padrão
Em geral, uma operação é idempotente se chamar a função várias vezes com sucesso deixa o sistema no mesmo estado que chamar a função uma vez com sucesso. Somente operações idempotentes são seguras para repetição. Exemplos de operações idempotentes incluem, sem limitação, todas as operações somente leitura e operações que só podem ser concluídas uma vez.
Por padrão, a biblioteca de cliente trata apenas RPCs implementados usando verbos GET ou
PUT como idempotentes. Isso pode ser muito conservador. Em alguns serviços, até mesmo algumas solicitações POST são idempotentes. Você sempre pode substituir a política de idempotência padrão para atender melhor às suas necessidades.
Algumas operações só são idempotentes se incluírem condições prévias. Por exemplo, "remover a versão mais recente se ela for Y" é idempotente, já que só pode ser executada uma vez.
De tempos em tempos, as bibliotecas de cliente recebem melhorias para tratar mais operações como idempotentes. Consideramos essas melhorias como correções de bugs e, portanto, não prejudiciais, mesmo que mudem o comportamento da biblioteca de cliente.
Embora seja seguro repetir uma operação, isso não significa que ela vai produzir o mesmo resultado na segunda tentativa em comparação com a primeira. Por exemplo, criar um recurso identificado de forma exclusiva pode ser seguro para novas tentativas, já que a segunda e as tentativas sucessivas falham e deixam o sistema no mesmo estado. No entanto, o cliente pode receber um erro "já existe" nas tentativas de nova tentativa.
Política de repetição padrão
Seguindo as diretrizes descritas em aip/194, a maioria das bibliotecas de cliente C++
só tenta novamente UNAVAILABLE erros do gRPC. Eles são mapeados para
StatusCode::kUnavailable. A política padrão é tentar novamente as solicitações por 30 minutos.
Os erros kUnavailable não indicam que o servidor não recebeu a solicitação. Esse código de erro é usado quando a solicitação não pode ser enviada, mas também quando ela é enviada e recebida pelo serviço, e a conexão é perdida antes de a resposta ser recebida pelo cliente. Além disso, se você pudesse determinar se a solicitação foi recebida
com sucesso, resolveria o
problema dos dois generais,
um resultado de impossibilidade conhecido em sistemas distribuídos.
Portanto, não é seguro repetir todas as operações que falham com
kUnavailable. A idempotência da operação também é importante.
Política de espera padrão
Por padrão, a maioria das bibliotecas usa uma estratégia de espera exponencial truncada com jitter. O intervalo inicial é de 1 segundo, o máximo é de 5 minutos, e o intervalo dobra após cada nova tentativa.
Mudar as políticas padrão de nova tentativa e espera
Cada biblioteca define uma estrutura *Option para configurar essas políticas. É possível fornecer essas opções ao criar a classe *Client ou até mesmo em cada solicitação.
Por exemplo, isso mostra como mudar as políticas de nova tentativa e espera exponencial para um cliente do Cloud Pub/Sub:
Consulte a documentação de cada biblioteca para encontrar os nomes e exemplos específicos dela.
Próximas etapas
- Consulte Configuração da biblioteca de cliente para saber mais sobre as opções comuns de configuração da biblioteca.