Nesta página, descrevemos o modelo de repetição usado pelas bibliotecas de cliente C++.
As bibliotecas de cliente emitem Chamadas de Procedimento Remoto (RPCs, na sigla em inglês) em seu nome. Essas RPCs podem falhar devido a erros transitórios. Os servidores são reiniciados, os balanceadores de carga fecham conexões sobrecarregadas ou inativas 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 que podem ser repetidos e operações que podem ser repetidas
Apenas erros transitórios podem ser tentados novamente. 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. Essa é quase sempre uma condição temporária, embora possa levar muito tempo para se recuperar. Esses erros são sempre possíveis de repetir, supondo que
a operação em si seja segura para novas tentativas. No contrato, os erros kPermissionDenied
exigem mais intervenção (geralmente por um ser humano) para serem resolvidos. Esses erros não são considerados "temporários" ou, pelo menos, não são transitórios 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, independentemente da natureza do erro. Isso inclui todas as operações que fazem alterações incrementais. Por exemplo, não é seguro repetir uma operação para remover "a versão mais recente de X", em que pode haver várias versões de um recurso chamado "X". Isso ocorre porque o autor da chamada provavelmente pretendia remover uma única versão, e tentar fazer essa solicitação novamente pode resultar na remoção de todas as versões.
Configurar loops de repetição
As bibliotecas de cliente aceitam três parâmetros de configuração diferentes para controlar os loops de repetição:
- O
*IdempotencyPolicy
determina se uma solicitação específica é idempotente. Somente essas solicitações são repetidas. - O
*RetryPolicy
determina (a) se um erro precisa ser considerado uma falha temporária e (b) por quanto tempo (ou quantas vezes) a biblioteca de cliente repete uma solicitação. - O
*BackoffPolicy
determina quanto tempo a biblioteca de cliente aguarda antes de emitir novamente a solicitação.
Política de idempotência padrão
Em geral, uma operação é idempotente quando chamada com sucesso a função várias vezes deixa o sistema no mesmo estado de que a função é chamada uma única vez. Apenas operações idempotentes são seguras para novas tentativas. Exemplos de operações idempotentes incluem, sem limitação, todas as operações somente leitura e operações que só podem ser bem-sucedidas uma vez.
Por padrão, a biblioteca de cliente trata apenas as RPCs implementadas com os verbos GET
ou
PUT
como idempotentes. Isso pode ser muito conservador. Em alguns serviços, mesmo algumas solicitações POST
são idempotentes. A qualquer momento, é possível substituir a política de
idempotência padrão para atender melhor às suas necessidades.
Algumas operações são idempotentes apenas quando incluem condições prévias. Por exemplo, "remover a versão mais recente se a versão mais recente for Y" é idempotente, já que só pode ser bem-sucedida 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 interruptivas, mesmo que mudem o comportamento da biblioteca de cliente.
Embora possa ser seguro repetir uma operação, isso não significa que ela produz o mesmo resultado na segunda tentativa em comparação com a primeira tentativa bem-sucedida. Por exemplo, criar um recurso identificado de maneira 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 repetição.
Política padrão de nova tentativa
Seguindo as diretrizes descritas em aip/194, a maioria das bibliotecas de cliente C++
só repete os erros gRPC UNAVAILABLE
. Eles estão mapeados para
StatusCode::kUnavailable
. A política padrão é repetir as solicitações por 30 minutos.
Observe que os erros kUnavailable
não indicam que o servidor não conseguiu receber a solicitação. Esse código de erro é usado quando a solicitação não pode ser enviada,
mas também é usado se a solicitação for enviada com êxito, recebida pelo
serviço e a conexão for perdida antes que a resposta seja recebida pelo
cliente. Além disso, se você pudesse determinar se a solicitação foi recebida
com êxito, poderá resolver o
problema dos dois gerais,
um conhecido resultado de impossibilidade 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 instabilidade. A espera inicial é de um segundo, a espera máxima é de cinco minutos e ela dobra após cada nova tentativa.
Alterar políticas padrão de nova tentativa e espera
Cada biblioteca define um struct *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, isto mostra como alterar as políticas de nova tentativa e espera para um cliente do Cloud Pub/Sub:
Consulte a documentação de cada biblioteca para ver os nomes e exemplos específicos delas.
Próximas etapas
- Consulte Configuração da biblioteca de cliente para saber mais sobre as opções comuns de configuração de bibliotecas.