Esta página explica como receber e confirmar mensagens usando o recurso de entrega exatamente uma vez do Pub/Sub, que permite rastrear e evitar o processamento duplicado de mensagens. Quando o recurso está ativado, o Pub/Sub fornece a seguinte semântica:
Os assinantes podem determinar se as confirmações de mensagens foram bem-sucedidas.
Nenhuma reentrega ocorre depois que a mensagem é confirmada.
Nenhuma reentrega ocorre enquanto uma mensagem está pendente. Uma mensagem é considerada pendente até que o prazo de confirmação expire ou a mensagem seja confirmada.
Em caso de várias entregas válidas, devido ao vencimento do prazo de confirmação ou à confirmação negativa iniciada pelo cliente, somente o ID de confirmação mais recente poderá ser usado para confirmar a mensagem. Todas as solicitações com um ID de confirmação anterior falham.
Com a entrega exatamente uma vez ativada, os assinantes podem garantir que as mensagens sejam processadas uma vez seguindo estas diretrizes:
Confirme as mensagens dentro do prazo de confirmação.
Mantenha informações sobre o progresso do processamento de uma mensagem até que ela seja confirmada.
Use as informações sobre o progresso do processamento de uma mensagem para evitar trabalhos duplicados quando uma confirmação falha.
Somente o tipo de assinatura por pull oferece suporte à entrega exatamente uma vez, incluindo assinantes que usam a API StreamingPull. As assinaturas de push e exportação não oferecem suporte à entrega exatamente uma vez.
O Pub/Sub oferece suporte à entrega exatamente uma vez, em uma região do Cloud, com base em um ID de mensagem exclusivo definido pelo Pub/Sub.
Versões recomendadas da biblioteca de cliente
- Para melhor desempenho, use a versão mais recente da biblioteca de cliente: Python v2.13.6 ou mais recente, Java v1.139.0 ou mais recente, PHP v1.39.0 ou mais recente, C# v3.2.0 ou mais recente, C++ v2.1.0, Go v1.25.1 ou mais recente, Node v3.2.0 ou mais recente e Ruby v2.12.1 ou mais recente.
Reentrega versus duplicação
É importante entender a diferença entre reentregas esperadas e inesperadas.
Uma reentrega pode ocorrer devido à confirmação negativa de uma mensagem iniciada pelo cliente ou quando o cliente não estende o prazo de confirmação da mensagem antes que ele expire. As reentregas são consideradas válidas e o sistema funciona conforme o esperado.
Para resolver problemas de reentrega, consulte Como lidar com duplicados.
Uma duplicação ocorre quando uma mensagem é reenviada após uma confirmação bem-sucedida ou antes do vencimento do prazo de confirmação.
Uma mensagem reenviada mantém o mesmo ID de mensagem entre as tentativas de reentrega.
As assinaturas com a entrega exatamente uma vez ativada não recebem entregas duplicadas.
Suporte à entrega exatamente uma vez em bibliotecas de cliente
As bibliotecas de cliente com suporte têm uma interface para confirmação com resposta (exemplo: Go). Você pode usar essa interface para verificar se a solicitação de confirmação foi bem-sucedida. Se a solicitação de confirmação for bem-sucedida, os clientes terão a garantia de não receber uma reentrega. Se a solicitação de confirmação falhar, os clientes poderão esperar uma reentrega.
Os clientes também podem usar as bibliotecas de cliente com suporte sem a interface de confirmação. No entanto, nesses casos, as falhas de confirmação podem levar a reentregas silenciosas de mensagens.
As bibliotecas de cliente com suporte têm interfaces para definir o tempo mínimo de extensão de concessão (exemplo: Go). É necessário definir o valor da extensão mínima de concessão como um número alto para evitar expirações de confirmação relacionadas à rede. O valor máximo é definido como 600 segundos.
Se você estiver usando a biblioteca de cliente Java e inicializar o assinante com um canal gRPC personalizado usando o
setChannelProvider()método, recomendamos que você também definamaxInboundMetadataSizecomo pelo menos 1 MB ao criar oTransportChannelProvider. Para essa configuração, você pode usar oInstantiatingGrpcChannelProvider.Builder.setMaxInboundMetadataSize()ou oManagedChannelBuilder.maxInboundMetadataSize()método.
Os valores padrão e o intervalo das variáveis relacionadas à entrega exatamente uma vez e os nomes das variáveis podem variar entre as bibliotecas de cliente. Por exemplo, na biblioteca de cliente Java, as variáveis a seguir controlam a entrega exatamente uma vez.
| Variável | Descrição | Valor |
|---|---|---|
setEnableExactlyOnceDelivery |
Ativa ou desativa a entrega exatamente uma vez. | true ou false Padrão=false |
minDurationPerAckExtension |
O tempo mínimo em segundos a ser usado para estender o prazo de confirmação da modificação. | Intervalo=0 a 600 Padrão=nenhum |
maxDurationPerAckExtension |
O tempo máximo em segundos a ser usado para estender o prazo de confirmação da modificação. | Intervalo=0 a 600 Padrão=nenhum |
No caso da entrega exatamente uma vez, a modifyAckDeadline ou acknowledgment
solicitação para o Pub/Sub falha quando o ID de confirmação já expirou. Nesses casos, o serviço considera o ID de confirmação expirado como inválido, já que uma entrega mais recente pode estar em andamento. Isso é intencional para a entrega exatamente uma vez. Em seguida, as solicitações acknowledgment e ModifyAckDeadline retornam uma resposta INVALID_ARGUMENT. Quando a entrega exatamente uma vez está desativada, essas solicitações retornam OK em casos de IDs de confirmação expirados.
Para garantir que as solicitações acknowledgment e ModifyAckDeadline tenham IDs de confirmação válidos, defina o valor de minDurationPerAckExtension como um número alto.
Considerações regionais
A garantia de entrega exatamente uma vez só se aplica quando os assinantes se conectam ao serviço na mesma região. Se o aplicativo de assinante estiver distribuído por várias regiões, isso poderá levar à entrega de mensagens duplicadas, mesmo quando a entrega exatamente uma vez estiver ativada. Os editores podem enviar mensagens para qualquer região, e a garantia de entrega exatamente uma vez ainda é mantida.
Quando você executa o aplicativo no Cloud de Confiance, ele se conecta ao endpoint do Pub/Sub na mesma região por padrão. Portanto, executar o aplicativo em uma única região no Cloud de Confiance geralmente garante que você esteja interagindo com uma única região.
Ao executar o aplicativo de assinante fora do Cloud de Confiance ou em várias regiões, você pode garantir que está se conectando a uma única região usando um endpoint de localização ao configurar o cliente do Pub/Sub Todos os endpoints de localização do Pub/Sub apontam para regiões únicas. Para saber mais sobre endpoints de localização, consulte Endpoints do Pub/Sub. Para uma lista de todos os endpoints de localização do Pub/Sub, consulte Lista de endpoints de localização.
Criar assinaturas com entrega exatamente uma vez
É possível criar uma assinatura com entrega exatamente uma vez usando o Cloud de Confiance console, a Google Cloud CLI, a biblioteca de cliente ou a API Pub/Sub.
Assinatura por pull
Console
Para criar uma assinatura por pull com entrega exatamente uma vez, siga estas etapas:
No Cloud de Confiance console do, acesse a página Assinaturas.
Clique em Criar assinatura.
Insira o ID da assinatura.
Escolha ou crie um tópico no menu suspenso.
A assinatura recebe mensagens do tópico.
Na seção Entrega exatamente uma vez, selecione Ativar entrega exatamente uma vez.
Clique em Criar.
gcloud
Para criar uma assinatura por pull com entrega exatamente uma vez, use o
gcloud pubsub subscriptions create
comando com a --enable-exactly-once-delivery flag:
gcloud pubsub subscriptions create SUBSCRIPTION_ID \ --topic=TOPIC_ID \ --enable-exactly-once-delivery
Substitua:
- SUBSCRIPTION_ID: o ID da assinatura a ser criada
- TOPIC_ID: o ID do tópico a ser anexado à assinatura
REST
Para criar uma assinatura com entrega exatamente uma vez, use o
projects.subscriptions.create
método.
PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID Authorization: Bearer $(gcloud auth print-access-token)
Substitua:
- PROJECT_ID: o ID do projeto para criar a assinatura
- SUBSCRIPTION_ID: o ID da assinatura a ser criada
Para criar uma assinatura por pull com entrega exatamente uma vez, especifique isso no corpo da solicitação:
{ "topic": "projects/PROJECT_ID/topics/TOPIC_ID", "enableExactlyOnceDelivery": true, }
Substitua:
- PROJECT_ID: o ID do projeto com o tópico
- TOPIC_ID: o ID do tópico a ser anexado à assinatura
C++
Antes de tentar esse exemplo, siga as instruções de configuração do C++ em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub C++.
C#
Antes de tentar esse exemplo, siga as instruções de configuração do C# em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub C# .
Go
O exemplo a seguir usa a versão principal da biblioteca de cliente do Go Pub/Sub (v2). Se você ainda estiver usando a biblioteca v1, consulte o guia de migração para a v2. Para conferir uma lista de exemplos de código v1, consulte os exemplos de código descontinuados.
Antes de tentar esse exemplo, siga as instruções de configuração do Go em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Go.
Java
Antes de tentar essa amostra, siga as instruções de configuração do Java em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub para Java (em inglês).
Python
Antes de tentar esse exemplo, siga as instruções de configuração do Python em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Python do Pub/Sub.
Node.js
Antes de tentar essa amostra, siga as instruções de configuração do Node.js em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub para Node.js (em inglês).
Node.js
Antes de tentar essa amostra, siga as instruções de configuração do Node.js em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub para Node.js (em inglês).
Ruby
O exemplo a seguir usa a biblioteca de cliente do Ruby Pub/Sub v3. Se você ainda estiver usando a biblioteca v2, consulte o guia de migração para a v3. Para conferir uma lista de exemplos de código do Ruby v2, consulte os exemplos de código descontinuados.
Antes de tentar esse exemplo, siga as instruções de configuração do Ruby em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Ruby.
PHP
Antes de tentar esse exemplo, siga as instruções de configuração do PHP em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub PHP.
Monitorar assinaturas de entrega exatamente uma vez
A
subscription/exactly_once_warning_count
métrica registra o número de eventos que
podem levar a possíveis reentregas (válidas ou duplicadas). Essa métrica conta as vezes em que o Pub/Sub não consegue processar solicitações associadas a IDs de confirmação (solicitação ModifyAckDeadline ou acknowledgment). Os motivos da falha podem ser baseados no servidor ou no cliente. Por exemplo, se a camada de persistência usada para manter as informações de entrega exatamente uma vez não estiver disponível, será um evento baseado no servidor. Se o cliente tentar confirmar uma mensagem com um ID de confirmação inválido, será um evento baseado no cliente.
Entender a métrica
subscription/exactly_once_warning_count captura eventos que podem ou não levar a reentregas reais e podem ser ruidosos com base no comportamento do cliente. Por exemplo, solicitações acknowledgment ou ModifyAckDeadline repetidas com IDs de confirmação inválidos incrementam a métrica repetidamente.
As métricas a seguir também são úteis para entender o comportamento do cliente:
subscription/expired_ack_deadlines_countmétrica mostra o número de expirações de ID de confirmação. As expirações de ID de confirmação podem levar a falhas nas solicitaçõesModifyAckDeadlineeacknowledgment.service.serviceruntime.googleapis.com/api/request_countmétrica pode ser usada para capturar falhas deModifyAckDeadlineouacknowledgmentsolicitações nos casos em que as solicitações chegam ao Cloud de Confiance by S3NS mas não chegam ao Pub/Sub. Há falhas que essa métrica não captura, por exemplo, quando os clientes estão desconectados do Cloud de Confiance by S3NS.
Na maioria dos casos de eventos de falha que podem ser repetidos, as bibliotecas de cliente com suporte refazem a solicitação automaticamente.
Cotas
As assinaturas de entrega exatamente uma vez estão sujeitas a requisitos de cota adicionais. Essas cotas são aplicadas a:
- Número de mensagens consumidas de assinaturas com entrega exatamente uma vez ativada por região.
- Número de mensagens confirmadas ou cujo prazo é estendido ao usar assinaturas com entrega exatamente uma vez ativada por região.
Para mais informações sobre essas cotas, consulte a tabela no tópico Cotas.
Entrega exatamente uma vez e assinaturas ordenadas
O Pub/Sub oferece suporte à entrega exatamente uma vez com entrega ordenada.
Ao usar a ordenação com entrega exatamente uma vez, o Pub/Sub espera que as confirmações estejam em ordem. Se as confirmações estiverem fora de ordem, o serviço falhará nas solicitações com erros temporários. Se o prazo de confirmação expirar antes de uma confirmação em ordem para a entrega, o cliente receberá uma reentrega da mensagem. Devido a isso, ao usar a ordenação com entrega exatamente uma vez, a capacidade de processamento do cliente é limitada a uma ordem de milhares de mensagens por segundo.
Entrega exatamente uma vez e assinaturas de push
O Pub/Sub oferece suporte à entrega exatamente uma vez apenas com assinaturas por pull.
Os clientes que consomem mensagens das assinaturas de push confirmam as mensagens respondendo às solicitações de push com uma resposta bem-sucedida. No entanto, os clientes não sabem se a assinatura do Pub/Sub recebeu a resposta e a processou. Isso é diferente das assinaturas por pull, em que as solicitações de confirmação são iniciadas pelos clientes e a assinatura do Pub/Sub responde se a solicitação foi processada. Por isso, a semântica de entrega exatamente uma vez não se alinha bem com as assinaturas de push.
Informações importantes
Se o prazo de confirmação não for especificado no momento da criação da assinatura, as assinaturas ativadas para entrega exatamente uma vez terão um prazo de confirmação padrão de 60 segundos.
Prazos de confirmação padrão mais longos são benéficos para evitar a reentrega causada por eventos de rede. As bibliotecas de cliente com suporte não usam o prazo de confirmação de assinatura padrão.
As assinaturas de entrega exatamente uma vez têm uma latência de publicação para inscrição significativamente maior em comparação com as assinaturas normais.
Se você precisar de alta capacidade de processamento, os clientes de entrega exatamente uma vez também precisarão usar o pull de streaming.
Uma assinatura pode receber várias cópias da mesma mensagem devido a duplicados do lado da publicação, mesmo com a entrega exatamente uma vez ativada. Os duplicados do lado da publicação podem ser devido a várias novas tentativas de publicação exclusivas pelo cliente de publicação ou pelo serviço do Pub/Sub. Várias publicações exclusivas pelo cliente de publicação, em novas tentativas, levam a reentregas com IDs de mensagem diferentes. Várias publicações exclusivas pelo serviço do Pub/Sub, para responder a uma solicitação de publicação do cliente, levam a reentregas com os mesmos IDs de mensagem.
É possível tentar novamente as falhas em
subscription/exactly_once_warning_count, e as bibliotecas de cliente com suporte refazem essas tentativas automaticamente. No entanto, não é possível tentar novamente as falhas relacionadas a IDs de confirmação inválidos.