O Pub/Sub é compatível com entrega de mensagens por push e pull. Para ter uma visão geral e comparar assinaturas de pull e push, consulte esta página. Este documento descreve a entrega por pull. Para ver uma discussão da entrega por push, consulte o Guia do assinante de push.
Pull assíncrono
O uso do pull assíncrono oferece uma maior capacidade em seu aplicativo, não exigindo que ele bloqueie novas mensagens. As mensagens podem ser recebidas no aplicativo usando-se um detector de mensagens de longa duração e reconhecidas uma de cada vez, conforme mostrado no exemplo abaixo. Os clientes Java, Python, .NET, Go e Ruby usam a API de serviço streamingPull para implementar a API do cliente assíncrona com eficiência.
Nem todas as bibliotecas de cliente são compatíveis com mensagens de pull assíncrono. Para saber mais sobre mensagens de pull síncrono, consulte Pull síncrono.
Para ver mais informações, consulte a documentação de referência da API da sua linguagem de programação.
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.
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.
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.
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.
Como processar atributos personalizados
Nesta amostra, você verá como enviar mensagens pull de maneira assíncrona e recuperar os atributos personalizados dos metadados:
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.
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.
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.
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.
Escuta de erros
Esta amostra exibe como lidar com erros que ocorrem durante a assinatura nas mensagens:
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 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.
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.
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.
Ruby
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.
Controle de fluxo de mensagens
O cliente assinante pode processar e reconhecer as mensagens mais lentamente do que o Pub/Sub as envia. Nesse caso:
É possível que um cliente tenha um backlog de mensagens por não ter capacidade para processar o volume de mensagens recebidas, mas outro cliente na rede tem. Este pode reduzir o backlog da assinatura, mas não consegue fazê-lo porque o primeiro cliente mantém um lease nas mensagens recebidas. Isso reduz a taxa de processamento geral, porque as mensagens ficam presas no primeiro cliente.
Como a biblioteca de cliente estende repetidamente o prazo de confirmação para as mensagens acumuladas, elas continuam a consumir recursos de memória, CPU e largura de banda. Dessa forma, o cliente assinante pode ficar sem recursos (como memória). Isso pode afetar negativamente a capacidade e a latência das mensagens de processamento.
Para atenuar os problemas acima, controle a taxa com que o assinante recebe as mensagens com os recursos de controle de fluxo do assinante. Esses recursos de controle de fluxo são ilustrados nas amostras a seguir:
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.
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.
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.
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.
De modo mais geral, a necessidade do controle de fluxo indica que as mensagens são publicadas com uma taxa maior do que são consumidas. Se esse for um estado constante, em vez de um pico transitório no volume de mensagens, pense em aumentar o número de instâncias do cliente assinante.
Controle de simultaneidade
A compatibilidade com a simultaneidade depende da linguagem de programação. Para implementações de linguagem compatíveis com linhas de execução paralelas, como Java e Go, as bibliotecas de cliente são a escolha padrão para o número de linhas de execução. Essa escolha pode não ser ideal para o aplicativo. Por exemplo, caso ache que o aplicativo assinante não está acompanhando o volume de mensagens recebidas nem está ligado à CPU, aumente a contagem de linhas de execução. Para operações de processamento de mensagens intensivas da CPU, diminua o número de linhas de execução.
A amostra seguir ilustra como controlar a simultaneidade em um assinante:
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.
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.
A compatibilidade com a simultaneidade depende da linguagem de programação. Consulte a documentação de referência de APIs para mais informações.
StreamingPull
O serviço Pub/Sub tem duas APIs para recuperar mensagens:
Sempre que possível, as bibliotecas de cliente do Cloud usam StreamingPull (em inglês) para máxima capacidade e menor latência. Embora seja possível que o uso da API StreamingPull diretamente nunca venha a acontecer, é importante entender algumas propriedades essenciais do StreamingPull e como ela difere do método Pull mais tradicional.
O método pull depende de um modelo de solicitação/resposta:
- O cliente envia uma solicitação de mensagens ao servidor.
- O servidor responde com zero ou mais mensagens e fecha a conexão.
A API do serviço StreamingPull depende de uma conexão bidirecional persistente para receber várias mensagens à medida que elas são disponibilizadas:
- O cliente envia uma solicitação ao servidor para estabelecer uma conexão.
- O servidor envia continuamente mensagens para o cliente conectado.
- A conexão é eventualmente encerrada pelo cliente ou pelo servidor.
Você fornece um callback para o assinante, e ele executa o callback para cada mensagem de maneira assíncrona. Se um assinante receber mensagens com a mesma chave de ordenação, as bibliotecas de cliente executarão sequencialmente o retorno de chamada. O serviço do Pub/Sub entrega essas mensagens ao mesmo assinante, com base no melhor esforço.
StreamingPull tem uma taxa de erro de 100%, o que é esperado
Os streams do StreamingPull sempre fecham com um status não OK. Observe que, ao contrário das RPCs normais, o status aqui é simplesmente uma indicação de que o stream foi interrompido, não de que as solicitações estão falhando. Portanto, ainda que a API StreamingPull tenha uma taxa de erro de 100% que pareça surpreendente, ela foi projetada dessa maneira.
Como diagnosticar erros do StreamingPull
Como os streams do StreamingPull sempre terminam com um erro, não é útil
examinar as métricas de encerramento de stream enquanto diagnostica erros. Em vez disso, concentre-se
na métrica de operação de mensagem StreamingPull
(subscription/streaming_pull_message_operation_count
). Procure estes erros:
- Erros
FAILED_PRECONDITION
podem ocorrer nos casos a seguir:- Pub/Sub tenta descriptografar uma mensagem com uma chave desativada do Cloud KMS.
- As assinaturas podem ser temporariamente suspensas se houver mensagens no backlog da assinatura criptografadas com uma chave do Cloud KMS desativada.
- Erros
UNAVAILABLE
StreamingPull: como lidar com grandes backlogs de pequenas mensagens
A pilha gRPC StreamingPull está otimizada para alta capacidade e, portanto, armazena mensagens em buffers. Isso pode ter algumas consequências se você está tentando processar grandes backlogs de pequenas mensagens, em vez de um stream estável de novas mensagens. Nessas condições, você pode ver mensagens entregues várias vezes, e o balanço de carga delas pode não ser realizado com eficácia entre os clientes.
O buffer entre o serviço Pub/Sub e o espaço de usuário da biblioteca de cliente é de aproximadamente 10 MB. Para entender o impacto desse buffer no comportamento da biblioteca de cliente, analise este exemplo:
- Há um backlog de 10.000 mensagens de 1 KB em uma assinatura.
- Cada mensagem leva um segundo para ser processada sequencialmente por uma instância de cliente com um único thread.
- A primeira instância de cliente para estabelecer uma conexão de StreamingPull com o serviço para essa inscrição preencherá seu buffer com todas as 10.000 mensagens.
- Leva 10.000 segundos (quase três horas) para processar o buffer.
- Nesse período, algumas das mensagens armazenadas em buffer excedem o prazo de confirmação e são reenviadas para o mesmo cliente, resultando em duplicatas.
- Quando várias instâncias de cliente estão em execução, as mensagens presas no buffer de um cliente não ficam disponíveis para nenhuma instância de cliente.
Essa situação não ocorrerá se as mensagens chegarem a uma taxa constante, e não como apenas um lote grande: o serviço nunca tem todos os 10 MB de mensagens por vez e, portanto, consegue balancear a carga de maneira eficaz entre vários assinantes.
Para resolver essa situação, use uma assinatura push ou a API Pull, atualmente disponível em algumas das bibliotecas de cliente do Cloud (consulte a seção Pull síncrono) e todas as bibliotecas de cliente da API. Para saber mais, consulte a documentação das bibliotecas de cliente.
Pull síncrono
Há casos em que o pull assíncrono não é adequado para seu aplicativo. Por exemplo, a lógica do aplicativo pode depender de um padrão de pesquisa para recuperar mensagens ou exigir um limite preciso em um número de mensagens recuperadas pelo cliente a qualquer momento. A compatibilidade do serviço com esses aplicativos depende do método de pull síncrono.
Veja a seguir um código de amostra para enviar por pull e confirmar um número fixo de mensagens:
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.
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.
PHP
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.
Protocolo
Solicitação:
POST https://pubsub.googleapis.com/v1/projects/myproject/subscriptions/mysubscription:pull
{
"returnImmediately": "false",
"maxMessages": "1"
}
Resposta:
200 OK
{
"receivedMessages": [{
"ackId": "dQNNHlAbEGEIBERNK0EPKVgUWQYyODM2LwgRHFEZDDsLRk1SK...",
"message": {
"data": "SGVsbG8gQ2xvdWQgUHViL1N1YiEgSGVyZSBpcyBteSBtZXNzYWdlIQ==",
"messageId": "19917247034"
}
}]
}
Solicitação:
POST https://pubsub.googleapis.com/v1/projects/myproject/subscriptions/mysubscription:acknowledge
{
"ackIds": [
"dQNNHlAbEGEIBERNK0EPKVgUWQYyODM2LwgRHFEZDDsLRk1SK..."
]
}
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.
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.
O Pub/Sub entrega uma lista de mensagens. Se a lista tiver várias mensagens, o Pub/Sub as ordena com a mesma chave de ordenação.
Para conseguir baixa latência de entrega de mensagens com pull síncrono, é importante ter muitas solicitações de pull pendentes ao mesmo tempo. À medida que a taxa de transferência do tópico aumenta, mais solicitações de pull são necessárias. Em geral, o pull assíncrono é indicado para aplicativos sensíveis à latência.
Pull síncrono com gerenciamento de lease
O processamento de uma mensagem individual pode exceder o prazo de confirmação pré-configurado, também conhecido como lease. Para evitar que essas mensagens sejam enviadas novamente, as bibliotecas de cliente permitem redefinir prazos de confirmação (exceto a biblioteca de cliente Go, que modifica automaticamente os prazos de confirmação de mensagens pesquisadas), conforme mostrado nas amostras abaixo:
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#.
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.
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.
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.
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.
Escalonamento
Pode ser necessário implementar um mecanismo de escalonamento no seu aplicativo de assinante para acompanhar o volume das mensagens. Como fazer isso depende do seu ambiente, mas ele geralmente será baseado nas métricas de backlog oferecidas por meio do Pacote de operações do Google Cloud do serviço de monitoramento. Para ver detalhes sobre como fazer isso para o Compute Engine, consulte Como escalonar com base em métricas do Cloud Monitoring.
Acesse a seção Pub/Sub da página lista de métricas do GCP para saber quais métricas podem ser monitoradas programaticamente.
Assim como ocorre com qualquer serviço distribuído, de vez em quando você terá de repetir cada solicitação.
Como lidar com duplicatas e forçar novas tentativas
Quando você não confirma uma mensagem antes do vencimento do prazo de confirmação, o Pub/Sub reenvia a mensagem. Como resultado, o Pub/Sub pode enviar mensagens duplicadas. Use o pacote de operações do Google Cloud
para monitorar as operações de confirmação com o
código de resposta expired
para detectar essa condição. Para conseguir esses dados, selecione a métrica Confirmar operações de mensagens e agrupe ou filtre pelo rótulo response_code
. Observe que response_code
é um rótulo do sistema em uma métrica. Ele não é uma métrica.

Para reduzir a taxa de duplicação, prolongue o prazo da mensagem.
- As bibliotecas de cliente prolongam o prazo automaticamente, mas há limites padrão de quanto o prazo pode ser prolongado.
- Use o método
modifyAckDeadline
para estender o prazo de confirmação se você estiver criando sua própria biblioteca de cliente.
Como alternativa, para forçar o Pub/Suba repetir uma mensagem, defina modifyAckDeadline
para 0.