Criar um pool de workers do Cloud Run para assinaturas do Pub/Sub baseadas em pull

1. Introdução

Visão geral

Os pools de workers são um recurso do Cloud Run projetado especificamente para cargas de trabalho sem solicitação, como filas de extração. Os pools de workers não têm os seguintes recursos:

  • Nenhum endpoint/URL
  • Não há necessidade de o contêiner implantado detectar solicitações em uma porta.
  • Sem escalonamento automático

Neste codelab, você vai criar um pool de workers que vai recuperar mensagens continuamente de uma assinatura de extração do Pub/Sub. Saiba mais sobre as assinaturas de pull do Pub/Sub na documentação e neste exemplo de código.

Conteúdo

  • Como criar e implantar em um pool de workers do Cloud Run
  • Como recuperar mensagens de uma assinatura do Pub/Sub baseada em pull

2. Configuração e requisitos

Primeiro, defina as variáveis de ambiente para este codelab:

export PROJECT_ID=<your_project_id>
export REGION=<your_region>

export WORKER_POOL_NAME=codelab-workers-pubsub
export SERVICE_ACCOUNT=worker-pools-sa
export SERVICE_ACCOUNT_EMAIL=${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com
export TOPIC=pull-pubsub-topic

Em seguida, configure a gcloud para usar o ID do projeto.

gcloud config set project $PROJECT_ID

Antes de começar a usar este codelab, ative as seguintes APIs executando:

gcloud services enable run.googleapis.com \
    cloudbuild.googleapis.com \
    artifactregistry.googleapis.com \
    pubsub.googleapis.com

Crie a conta de serviço executando:

gcloud iam service-accounts create ${SERVICE_ACCOUNT} \
  --display-name="Service account for worker pool codelab"

Por fim, conceda à sua conta de serviço do Cloud Run acesso ao Pub/Sub:

gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member serviceAccount:$SERVICE_ACCOUNT_EMAIL \
    --role='roles/pubsub.admin'

3. Criar o pool de workers do Cloud Run

Primeiro, crie um diretório para o código do pool de workers:

mkdir codelab-worker-pools
cd codelab-worker-pools

Em seguida, crie um arquivo chamado package.json.

{
    "name": "codelab-worker-pools",
    "version": "1.0.0",
    "description": "A codelab example of a Cloud Run worker pool retrieving messages from a Pull-based PubSub subscription",
    "main": "index.js",
    "scripts": {
        "start": "node index.js"
    },
    "engines": {
        "node": ">=22.0.0"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
        "@google-cloud/pubsub": "^5.1.0"
    }
}

Agora, crie um arquivo chamado index.js:

'use strict';

const subscriptionNameOrId = 'pull-pubsub-topic';

const { PubSub } = require('@google-cloud/pubsub');

// Creates a Pub/Sub client; cache this for further use.
const pubSubClient = new PubSub();

// References an existing subscription.
const subscription = pubSubClient.subscription(subscriptionNameOrId);

// This function is called when a shutdown signal is received.
const handleShutdown = async (signal) => {
  console.log(`\n${signal} signal caught. Shutting down gracefully...`);

  try {
    // 1. Stop listening for new messages. The `close()` method returns a Promise.
    console.log('Closing Pub/Sub subscription...');
    await subscription.close();
    console.log('Pub/Sub subscription closed.');

    // 2. Add any other cleanup logic here, like closing database connections.

  } catch (err) {
    console.error('Error during graceful shutdown:', err);
  } finally {
    console.log('Worker Pool exited.');
    process.exit(0);
  }
};

// Listen for termination signals.
// SIGINT handles Ctrl+C locally.
// SIGTERM handles signals from services like Cloud Run.
process.on('SIGINT', () => handleShutdown('SIGINT'));
process.on('SIGTERM', () => handleShutdown('SIGTERM'));

// ------------------ Pub/Sub Message Handling ------------------

// Create an event handler to process incoming messages.
const messageHandler = message => {
  console.log(`Received message ${message.id}:`);
  console.log(`\tData: ${message.data}`);
  console.log(`\tAttributes: ${JSON.stringify(message.attributes)}`);

  // Ack the message so it is not sent again.
  message.ack();
};

// Register the message handler and listen for messages.
subscription.on('message', messageHandler);

console.log(
  `Worker started. Listening for messages on "${subscriptionNameOrId}".`
);
console.log('If running locally, press Ctrl+C to quit.');

// The application will now listen for messages indefinitely until a shutdown
// signal is received.

4. Implantar o pool de workers

Crie o pool de workers do Cloud Run executando o seguinte comando:

gcloud beta run worker-pools deploy $WORKER_POOL_NAME --region=$REGION --source .

Esse comando cria a imagem da origem e implanta o job. Essa operação leva alguns minutos.

5. Publicar uma mensagem no Pub/Sub

Criar um tópico do Pub/Sub

gcloud pubsub topics create $TOPIC

Criar uma assinatura por pull do Pub/Sub

gcloud pubsub subscriptions create codelab-subscription --topic=$TOPIC

Execute o comando a seguir para publicar uma mensagem no tópico do Pub/Sub.

gcloud pubsub topics publish $TOPIC --message "Hello Worker Pools"

Verificar os registros do pool de workers

gcloud logging read 'resource.type="cloud_run_worker_pool" AND resource.labels.worker_pool_name="'$WORKER_POOL_NAME'" AND resource.labels.location="'$REGION'"' --limit 10

Você vai ver Hello Worker Pools nos registros.

6. Excluir o pool de workers

Como os pools de workers são executados continuamente, é necessário excluí-los.

gcloud beta run worker-pools delete $WORKER_POOL_NAME --region $REGION

7. Parabéns!

Parabéns por concluir o codelab!

Recomendamos que você consulte a documentação do Cloud Run.

O que aprendemos

  • Como criar e implantar em um pool de workers do Cloud Run
  • Como recuperar mensagens de uma assinatura do Pub/Sub baseada em pull

8. Limpar

Para excluir o pool de workers do Cloud Run, acesse o console do Cloud Run em https://console.cloud.google.com/run e exclua o pool de workers codelab-workers-pubsub.

Para excluir todo o projeto, acesse Gerenciar recursos, selecione o projeto criado na etapa 2 e escolha "Excluir". Se você excluir o projeto, vai precisar mudar de projeto no SDK do Cloud. Para conferir a lista de todos os projetos disponíveis, execute gcloud projects list.