Esta página explica como receber e confirmar mensagens usando o recurso "exatamente uma vez" do Pub/Sub, que permite rastrear e evitar o processamento duplicado de mensagens. Quando o recurso é ativado, o Pub/Sub oferece a seguinte semântica:
Os assinantes podem determinar se os avisos de mensagem foram bem-sucedidos.
Nenhuma nova entrega ocorre depois que a mensagem é confirmada.
Não há nova entrega enquanto uma mensagem está pendente. Uma mensagem é considerada pendente até que o prazo de confirmação expire ou a mensagem seja confirmada.
No caso de várias entregas válidas, devido ao vencimento do prazo de confirmação ou confirmação negativa iniciada pelo cliente, apenas o ID de confirmação mais recente pode ser usado para confirmar a mensagem. Todas as solicitações com um ID de confirmação anterior falham.
Com a opção "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.
Manter 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 trabalho duplicado quando um aviso falhar.
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 são compatíveis com a 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 único definido pelo Pub/Sub.
Versões recomendadas da biblioteca de cliente
- Para ter a melhor performance, use a versão mais recente da biblioteca de cliente, Python v2.13.6 ou mais recente, Java v1.120.11 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.
Reenvio em vez de cópia
É importante entender a diferença entre reentregas esperadas e inesperadas.
Uma reentrega pode acontecer devido a uma 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 duplicatas.
Uma mensagem duplicada é quando ela é reenviada após uma confirmação bem-sucedida ou antes do prazo de confirmação expirar.
Uma mensagem reenviada mantém o mesmo ID entre as tentativas de reenvio.
As assinaturas com a entrega exatamente uma vez ativada não recebem envios duplicados.
Suporte à entrega exatamente uma vez nas bibliotecas de cliente
As bibliotecas de cliente com suporte têm uma interface de confirmação com resposta (por exemplo, Go). Use 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 não receberão uma nova entrega. Se a solicitação de confirmação falhar, os clientes poderão esperar uma nova entrega.
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 reenvios silenciosos de mensagens.
As bibliotecas de cliente com suporte têm interfaces para definir o tempo mínimo de extensão de concessão (por exemplo, Go). Defina o valor da extensão mínima do contrato de aluguel como um número alto para evitar a expiração de confirmação relacionada à rede. O valor máximo é definido como 600 segundos.
Os valores e o intervalo padrão das variáveis relacionadas ao envio exatamente uma vez e os nomes das variáveis podem ser diferentes nas 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 para estender o prazo de confirmação de modificação. | Intervalo=0 a 600. Padrão=nenhum |
maxDurationPerAckExtension |
O tempo máximo em segundos para estender o prazo de confirmação de modificação. | Intervalo=0 a 600. Padrão=nenhum |
No caso de entrega exatamente uma vez, a solicitação modifyAckDeadline
ou acknowledgment
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 já estar em andamento. Isso é feito por design para entrega
exatamente uma vez. 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 do assinante estiver distribuído em várias regiões, isso poderá resultar em 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 envio exato ainda é mantida.
Quando você executa o aplicativo no Google Cloud, ele se conecta por padrão ao endpoint do Pub/Sub na mesma região. Portanto, executar seu aplicativo em uma única região do Google Cloud geralmente garante que você esteja interagindo com uma única região.
Ao executar o aplicativo de assinante fora do Google Cloud ou em várias regiões, é possível garantir que você 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 local 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 console do Google Cloud, a Google Cloud CLI, a biblioteca de cliente ou a API Pub/Sub.
Assinatura de pull
Console
Para criar uma assinatura de pull com entrega exatamente uma vez, siga estas etapas:
No console do Google Cloud, 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 de pull com entrega exatamente uma vez, use o
comando gcloud pubsub subscriptions create
com a flag --enable-exactly-once-delivery
:
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
método
projects.subscriptions.create
.
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 de 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
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 Java.
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 Pub/Sub Python.
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 Node.js.
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 Node.js.
Ruby
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.
Assinar com entrega de mensagens exatamente uma vez
Confira a seguir alguns exemplos de código para assinar com entrega exatamente única usando a biblioteca de cliente.
Assinatura de pull
Go
Antes de testar esta amostra, siga as instruções de configuração do Go no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Go.
Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.
Java
Antes de testar esta amostra, siga as instruções de configuração do Java no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Java.
Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.
Node.js
Antes de testar esta amostra, siga as instruções de configuração do Node.js no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Node.js.
Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.
PHP
Antes de testar esta amostra, siga as instruções de configuração do PHP no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub PHP.
Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.
Python
Antes de testar esta amostra, siga as instruções de configuração do Python no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Python.
Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.
Ruby
Antes de testar esta amostra, siga as instruções de configuração do Ruby no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Ruby.
Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.
C++
Antes de testar esta amostra, siga as instruções de configuração do C++ no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub C++.
Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.
C#
Antes de testar esta amostra, siga as instruções de configuração do C# no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub C#.
Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.
Node.js (TypeScript)
Antes de testar esta amostra, siga as instruções de configuração do Node.js no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Node.js.
Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.
Monitorar assinaturas de entrega exatamente uma vez
A métrica
subscription/exactly_once_warning_count
registra o número de eventos que
podem levar a possíveis novas entregas (válidas ou duplicadas). Essa métrica conta as
vezes que o Pub/Sub falha ao processar solicitações associadas a
IDs de confirmação (solicitações 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 envio exato não estiver disponível, será um evento baseado em 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
O subscription/exactly_once_warning_count
captura eventos que podem ou não
levar a novas entregas e pode ser barulhento com base no comportamento do cliente. Por
exemplo: solicitações repetidas de acknowledgment
ou ModifyAckDeadline
com IDs de
confirmação inválidos incrementam a métrica várias vezes.
As métricas a seguir também são úteis para entender o comportamento do cliente:
A métrica
subscription/expired_ack_deadlines_count
mostra o número de expirações de ID de confirmação. A expiração do ID de confirmação pode causar falhas nas solicitaçõesModifyAckDeadline
eacknowledgment
.A métrica
service.serviceruntime.googleapis.com/api/request_count
pode ser usada para capturar falhas de solicitaçõesModifyAckDeadline
ouacknowledgment
em casos em que as solicitações chegam ao Google Cloud, mas não ao Pub/Sub. Há falhas que essa métrica não vai capturar, por exemplo, quando os clientes são desconectados do Google Cloud.
Na maioria dos casos de falhas que podem ser repetidas, as bibliotecas de cliente com suporte tentam a solicitação novamente automaticamente.
Cotas
As assinaturas de entrega exatamente uma vez estão sujeitas a requisitos de cota adicionais. Essas cotas são aplicadas em:
- Número de mensagens consumidas de assinaturas com entrega exatamente uma vez ativada por região.
- Número de mensagens confirmadas ou com prazo estendido ao usar assinaturas com envio exato uma vez ativado 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 ao envio único com envio ordenado.
Ao usar a ordenação com entrega única, o Pub/Sub espera que os avisos estejam em ordem. Se os avisos estiverem fora de ordem, o serviço vai falhar nas solicitações com erros temporários. Se o prazo de confirmação expirar antes de uma confirmação na ordem para a entrega, o cliente vai receber uma nova entrega da mensagem. Por isso, quando você usa a ordenação com entrega exatamente uma vez, a capacidade do cliente é limitada a uma ordem de mil mensagens por segundo.
Entrega exatamente uma vez e assinaturas de push
O Pub/Sub oferece suporte à entrega exatamente uma vez apenas com assinaturas de 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 de 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 envio exatamente uma vez não se alinha bem com as assinaturas de push.
Informações úteis
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 reenvios causados 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 uma alta capacidade de processamento, seus 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 duplicações do lado da publicação, mesmo com a entrega exatamente uma vez ativada. As duplicações do lado da publicação podem ser causadas por várias novas tentativas de publicação exclusivas do cliente de publicação ou do serviço do Pub/Sub. Várias publicações únicas pelo cliente de publicação, em várias tentativas, levam a novas entregas com IDs de mensagem diferentes. Várias publicações únicas pelo serviço do Pub/Sub, para responder a uma solicitação de publicação do cliente, levam a reenvios com os mesmos IDs de mensagem.
É possível repetir as falhas em
subscription/exactly_once_warning_count
, e as bibliotecas de cliente com suporte tentam novamente automaticamente. No entanto, falhas relacionadas a IDs de confirmação inválidos não podem ser repetidas.