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 oferece a seguinte semântica:
Os assinantes podem determinar se os reconhecimentos de mensagens foram bem-sucedidos.
Nenhuma nova entrega ocorre depois que a mensagem é confirmada.
Nenhuma nova entrega ocorre enquanto uma mensagem está pendente. Uma mensagem é considerada pendente até que o prazo de confirmação expire ou que ela seja confirmada.
Em caso de várias entregas válidas, devido à expiração do prazo de confirmação ou à confirmação negativa iniciada pelo cliente, somente 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 vão falhar.
Com a opção "exatamente uma vez" ativada, os assinantes podem garantir que as mensagens sejam processadas uma vez seguindo estas diretrizes:
Confirmar mensagens dentro do prazo.
Manter informações sobre o progresso do processamento de uma mensagem até que ela seja confirmada com sucesso.
Use as informações sobre o progresso do processamento de uma mensagem para evitar trabalho duplicado quando um reconhecimento 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 são compatíveis com a entrega exatamente uma vez.
O Pub/Sub oferece suporte à entrega exatamente uma vez, em uma região da nuvem, com base em um ID de mensagem exclusivo definido pelo Pub/Sub.
Versões recomendadas da biblioteca de cliente
- Para ter o 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.
Reenvio x duplicação
É importante entender a diferença entre novas entregas 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 novas entregas são consideradas válidas e o sistema funciona como esperado.
Para resolver problemas de reenvio, consulte Como lidar com duplicados.
Uma mensagem é duplicada quando é enviada novamente após uma confirmação bem-sucedida ou antes do vencimento do prazo de confirmação.
Uma mensagem reencaminhada mantém o mesmo ID entre as tentativas de reencaminhamento.
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 compatíveis 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 não vão receber uma nova entrega. Se a solicitação de confirmação falhar, os clientes podem esperar uma nova entrega.
Os clientes também podem usar as bibliotecas de cliente compatíveis sem a interface de confirmação. No entanto, nesses casos, as falhas de confirmação podem levar a novas entregas silenciosas de mensagens.
As bibliotecas de cliente compatíveis têm interfaces para definir o tempo mínimo de extensão do contrato de locação (exemplo: Go). Defina um valor alto para a extensão mínima do contrato de locação para evitar expirações de confirmação relacionadas à rede. O valor máximo é de 600 segundos.
Se você estiver usando a biblioteca de cliente Java e inicializar o assinante com um canal gRPC personalizado usando o método
setChannelProvider()
, recomendamos que você também definamaxInboundMetadataSize
como pelo menos 1 MB ao criar oTransportChannelProvider
. Para essa configuração, use o métodoInstantiatingGrpcChannelProvider.Builder.setMaxInboundMetadataSize()
ouManagedChannelBuilder.maxInboundMetadataSize()
.
Os valores e intervalos padrão 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 seguintes variáveis controlam a entrega exatamente uma vez.
Variável | Descrição | Valor |
---|---|---|
setEnableExactlyOnceDelivery |
Ativa ou desativa a entrega exatamente uma vez. | true ou false Default=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 para usar na extensão do prazo de confirmação da modificação. | Intervalo=0 a 600 Padrão=nenhum |
No caso da 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 estar em andamento. Isso ocorre por design para entrega
exatamente uma vez. Em seguida, você verá as solicitações acknowledgment
e ModifyAckDeadline
retornarem 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 assinante estiver distribuído em 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 única ainda é mantida.
Quando você executa o aplicativo em Google Cloud, por padrão ele se conecta ao endpoint do Pub/Sub na mesma região. Portanto, executar o aplicativo em uma única região dentro do Google Cloudgeralmente 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 a conexão com uma única região usando um endpoint de local 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 regionais, 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 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 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 única, 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 alguns exemplos de código para fazer a inscrição com entrega exatamente uma vez 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 novas entregas (válidas ou duplicadas). Essa métrica conta as
vezes em que o Pub/Sub não processa solicitações associadas a
IDs de confirmação (solicitação ModifyAckDeadline
ou acknowledgment
). Os motivos
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.
Entenda a métrica
subscription/exactly_once_warning_count
captura eventos que podem ou não levar a novas entregas e pode ser ruidoso 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 repetidamente.
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. O vencimento 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 captura, por exemplo, quando os clientes são desconectados do Google Cloud.
Na maioria dos casos de eventos de falha que podem ser repetidos, as bibliotecas de cliente compatíveis tentam fazer a solicitação novamente de forma automática.
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 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 única, o Pub/Sub espera que os reconhecimentos estejam em ordem. Se os reconhecimentos 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 em ordem para a entrega, o cliente vai receber uma nova entrega da mensagem. Por isso, quando você usa o pedido 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 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 e processou a resposta. 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 com êxito. Por isso, a semântica de entrega 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 de CreateSubscription, as assinaturas com entrega exatamente uma vez ativada terão um prazo de confirmação padrão de 60 segundos.
Prazos de confirmação padrão mais longos são úteis para evitar nova entrega causada por eventos de rede. As bibliotecas de cliente compatíveis 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 do que as assinaturas regulares.
Se você precisar de alta capacidade de processamento, os clientes de entrega exatamente uma vez também precisarão usar o streaming pull.
Uma assinatura pode receber várias cópias da mesma mensagem devido a duplicatas do lado da publicação, mesmo com a entrega exatamente uma vez ativada. Duplicatas do lado da publicação podem ocorrer devido a várias novas tentativas de publicação exclusivas pelo cliente de publicação ou pelo serviço Pub/Sub. Várias publicações exclusivas pelo cliente de publicação, em várias tentativas, levam a novas entregas com IDs de mensagens 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 reenvios com os mesmos IDs de mensagem.
É possível tentar novamente em
subscription/exactly_once_warning_count
, e as bibliotecas de cliente compatíveis fazem isso automaticamente. No entanto, não é possível repetir falhas relacionadas a IDs de confirmação inválidos.