Ajusta automáticamente la escala de los grupos de trabajadores según el volumen de la cola de Pub/Sub

En este instructivo, se muestra cómo implementar un grupo de trabajadores de Cloud Run para procesar mensajes de Pub/Sub y ajustar automáticamente la escala de tus instancias de consumidor en función de la profundidad de la cola con el ajuste de escala automático de métricas externas de Cloud Run (CREMA).

Objetivos

En este instructivo, podrás:

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.

Es posible que los usuarios Google Cloud nuevos decumplan con los requisitos para acceder a una prueba gratuita.

Antes de comenzar

  1. Accede a tu Google Cloud cuenta de. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  5. Verify that billing is enabled for your Google Cloud project.

  6. Habilita las APIs de Cloud Run, Parameter Manager, Artifact Registry, Pub/Sub y Cloud Build.

    Roles necesarios para habilitar las APIs

    Para habilitar las APIs, necesitas el rol de IAM de administrador de Service Usage (roles/serviceusage.serviceUsageAdmin), que contiene el permiso serviceusage.services.enable. Obtén más información para otorgar roles.

    Habilitar las API

  7. Instala e inicializa gcloud CLI.
  8. Actualiza los componentes, como se indica a continuación:
    gcloud components update
  9. En este instructivo, se utilizan varias variables de entorno. Para mejorar la depuración, ejecuta el siguiente comando para generar un error cuando hagas referencias a variables de entorno locales no establecidas:
    set -u
  10. Establece las siguientes variables de configuración para CREMA que se usan en este instructivo:
    export PROJECT_ID=PROJECT_ID
    export REGION=us-central1
    export TOPIC_ID=crema-pubsub-topic
    export SUBSCRIPTION_ID=crema-subscription
    export CREMA_SA_NAME=crema-service-account
    export CONSUMER_SA_NAME=consumer-service-account
    export CONSUMER_WORKER_POOL_NAME=worker-pool-consumer
    export CREMA_SERVICE_NAME=my-crema-service
    Reemplaza PROJECT_ID por el ID de tu Google Cloud proyecto.
  11. Ejecuta el siguiente comando para configurar el ID del proyecto:
    gcloud config set project $PROJECT_ID
  12. Se te cobrará por tu servicio de ajuste de escala de Cloud Run según la frecuencia con la que actives el ajuste de escala. Para obtener más información, calcula los costos con la calculadora de precios.

Roles obligatorios

Si quieres obtener los permisos que necesitas para completar el instructivo, pídele a tu administrador que te otorgue los siguientes roles de IAM en tu proyecto:

Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

También puedes obtener los permisos necesarios mediante roles personalizados o cualquier otro rol predefinido.

Crear un tema de Pub/Sub y una suscripción

Para ajustar automáticamente la escala de tu trabajador, crea una suscripción de extracción para tu aplicación de consumidor con los siguientes pasos:

  1. Crea un tema de Pub/Sub que represente un feed de mensajes:

    gcloud pubsub topics create $TOPIC_ID
    
  2. Crea una suscripción de extracción para consumir mensajes de tu tema de Pub/Sub:

    gcloud pubsub subscriptions create $SUBSCRIPTION_ID --topic=$TOPIC_ID
    

Crea cuentas de servicio personalizadas

En este instructivo, se requieren las siguientes dos cuentas de servicio con los permisos mínimos necesarios para usar los recursos aprovisionados:

  • Cuenta de servicio del consumidor: Identidad para el grupo de trabajadores del consumidor que procesa mensajes. Ejecuta el siguiente comando para crear la cuenta de servicio del consumidor:

    gcloud iam service-accounts create $CONSUMER_SA_NAME \
      --display-name="Pub/Sub consumer service account"
    
  • Cuenta de servicio de CREMA: Identidad para el escalador automático. Ejecuta el siguiente comando para crear la cuenta de servicio de CREMA:

    gcloud iam service-accounts create $CREMA_SA_NAME \
      --display-name="CREMA service account"
    

Otorga permisos adicionales a tus cuentas de servicio personalizadas

Para escalar el grupo de trabajadores, otorga los siguientes permisos en las cuentas de servicio personalizadas:

  1. Otorga permiso a tu cuenta de servicio de CREMA para leer desde Parameter Manager:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/parametermanager.parameterViewer"
    
  2. Otorga a tu cuenta de servicio de CREMA el permiso para escalar el grupo de trabajadores:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/run.developer"
    
  3. Otorga a tu cuenta de servicio de CREMA el rol de usuario de la cuenta de servicio:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/iam.serviceAccountUser"
    
  4. Otorga permiso a tu cuenta de servicio de CREMA para ver las métricas:

     gcloud projects add-iam-policy-binding $PROJECT_ID \
       --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
       --role="roles/monitoring.viewer"
    
  5. Otorga permiso a tu cuenta de servicio de CREMA para escribir métricas:

     gcloud projects add-iam-policy-binding $PROJECT_ID \
       --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
       --role="roles/monitoring.metricWriter"
    
  6. Otorga permiso a tu cuenta de servicio de CREMA para ver los mensajes de Pub/Sub:

    gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
      --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/pubsub.viewer"
    
  7. Otorga permiso a tu cuenta de servicio del consumidor para extraer mensajes de la suscripción:

    gcloud pubsub subscriptions add-iam-policy-binding $SUBSCRIPTION_ID \
      --member="serviceAccount:$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/pubsub.subscriber"
    

Implementa un grupo de trabajadores de Cloud Run

Para implementar un grupo de trabajadores que consuma mensajes de suscripciones de Pub/Sub, sigue estos pasos:

  1. Crea una carpeta llamada consumer y cambia el directorio a ella:

    mkdir consumer
    cd consumer
    
  2. Crea un archivo llamado worker.py y agrega el siguiente código:

    import os
    import time
    from google.cloud import pubsub_v1
    from concurrent.futures import TimeoutError
    
    # Configuration
    PROJECT_ID = os.environ.get('PROJECT_ID')
    SUBSCRIPTION_ID = os.environ.get('SUBSCRIPTION_ID')
    
    subscription_path = f"projects/{PROJECT_ID}/subscriptions/{SUBSCRIPTION_ID}"
    
    print(f"Worker Pool instance starting. Watching {subscription_path}...")
    
    subscriber = pubsub_v1.SubscriberClient()
    
    def callback(message):
        try:
            data = message.data.decode("utf-8")
            print(f"Processing job: {data}")
            time.sleep(5)  # Simulate work
            print(f"Done {data}")
            message.ack()
        except Exception as e:
            print(f"Error processing message: {e}")
            message.nack()
    
    streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
    print(f"Listening for messages on {subscription_path}...")
    
    # Wrap subscriber in a 'with' block to automatically call close() when done.
    with subscriber:
        try:
            # When `timeout` is not set, result() will block indefinitely,
            # unless an exception is encountered first.
            streaming_pull_future.result()
        except TimeoutError:
            streaming_pull_future.cancel()  # Trigger the shutdown.
            streaming_pull_future.result()  # Block until the shutdown is complete.
        except Exception as e:
            print(f"Streaming pull failed: {e}")
    
  3. Crea un Dockerfile y agrega el siguiente código:

    FROM python:3.12-slim
    RUN pip install google-cloud-pubsub
    COPY worker.py .
    CMD ["python", "-u", "worker.py"]
    
  4. Implementa el grupo de trabajadores del consumidor con 0 instancias para que CREMA escale:

    gcloud beta run worker-pools deploy $CONSUMER_WORKER_POOL_NAME \
      --source . \
      --region $REGION \
      --service-account="$CONSUMER_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
      --instances=0 \
      --set-env-vars PROJECT_ID=$PROJECT_ID,SUBSCRIPTION_ID=$SUBSCRIPTION_ID
    

Implementa el servicio de escalador automático CREMA

Una vez que implementes el grupo de trabajadores para consumir mensajes de Pub/Sub, configura el escalador automático de CREMA para aprovisionar instancias de trabajador en función de la cantidad de mensajes.

Configurar el escalador automático

En este instructivo, se usa el Parameter Manager para almacenar el archivo de configuración YAML para CREMA.

  1. Crea un parámetro en Parameter Manager para almacenar versiones de parámetros para CREMA:

    PARAMETER_ID=crema-config
    PARAMETER_REGION=global
    gcloud parametermanager parameters create $PARAMETER_ID --location=$PARAMETER_REGION --parameter-format=YAML
    
  2. Navega al directorio raíz de tu proyecto ejecutando el siguiente comando:

    cd
    
  3. En tu directorio raíz, crea un archivo YAML, my-crema-config.yaml para definir la configuración del escalador automático:

    apiVersion: crema/v1
    kind: CremaConfig
    spec:
      pollingInterval: 30
      triggerAuthentications:
        - metadata:
            name: adc-trigger-auth
          spec:
            podIdentity:
              provider: gcp
      scaledObjects:
        - spec:
            scaleTargetRef:
              name: projects/PROJECT_ID/locations/us-central1/workerpools/worker-pool-consumer
            triggers:
              - type: gcp-pubsub
                metadata:
                  subscriptionName: "crema-subscription"
                  # Target number of undelivered messages per worker instance
                  value: "10"
                  mode: "SubscriptionSize"
                authenticationRef:
                  name: adc-trigger-auth
    

    Reemplaza PROJECT_ID por el Google Cloud ID del proyecto.

  4. Sube tu archivo YAML local como una nueva versión del parámetro:

    LOCAL_YAML_CONFIG_FILE=my-crema-config.yaml
    PARAMETER_VERSION=1
    
    gcloud parametermanager parameters versions create $PARAMETER_VERSION \
      --location=$PARAMETER_REGION \
      --parameter=$PARAMETER_ID \
      --payload-data-from-file=$LOCAL_YAML_CONFIG_FILE
    
  5. Ejecuta el siguiente comando para verificar que la adición de parámetros se realizó correctamente:

    gcloud parametermanager parameters versions list \
    --parameter=$PARAMETER_ID \
    --location=$PARAMETER_REGION
    

    Deberías ver la ruta de acceso del parámetro, como projects/PROJECT_ID/locations/global/parameters/crema-config/versions/1.

Implementa el servicio para escalar tus cargas de trabajo

Para implementar el servicio para escalar tu grupo de trabajadores, ejecuta el siguiente comando con una imagen de contenedor precompilada:

CREMA_CONFIG_PARAM_VERSION=projects/$PROJECT_ID/locations/$PARAMETER_REGION/parameters/$PARAMETER_ID/versions/$PARAMETER_VERSION
IMAGE=us-central1-docker.pkg.dev/cloud-run-oss-images/crema-v1/autoscaler:1.0

gcloud beta run deploy $CREMA_SERVICE_NAME \
  --image=${IMAGE} \
  --region=${REGION} \
  --service-account="${CREMA_SA_NAME}" \
  --no-allow-unauthenticated \
  --no-cpu-throttling \
  --base-image=us-central1-docker.pkg.dev/serverless-runtimes/google-24/runtimes/java25 \
  --labels=created-by=crema \
  --set-env-vars="CREMA_CONFIG=${CREMA_CONFIG_PARAM_VERSION},OUTPUT_SCALER_METRICS=True"

Prueba tu servicio de ajuste de escala automático

Para probar tu servicio de CREMA, crea una secuencia de comandos que genere 100 mensajes y los envíe a la cola de Pub/Sub:

  1. En tu directorio raíz, crea un archivo llamado load-pubsub.sh y agrega el siguiente código:

    #!/bin/bash
    
    TOPIC_ID=${TOPIC_ID}
    PROJECT_ID=${PROJECT_ID}
    NUM_MESSAGES=100
    
    echo "Publishing $NUM_MESSAGES messages to topic $TOPIC_ID..."
    
    for i in $(seq 1 $NUM_MESSAGES); do
      gcloud pubsub topics publish $TOPIC_ID --message="job-$i" --project=$PROJECT_ID &
      if (( $i % 10 == 0 )); then
        wait
        echo "Published $i messages..."
      fi
    done
    wait
    echo "Done. All messages published."
    
  2. Ejecuta la prueba de carga:

    chmod +x load-pubsub.sh
    ./load-pubsub.sh
    

Este comando genera y envía 100 mensajes a la suscripción de Pub/Sub.

Supervisa el ajuste de escala

Una vez que se complete la secuencia de comandos load-pubsub.sh, espera de tres a cuatro minutos antes de verificar registros para el servicio, my-crema-service. El servicio de escalador automático de CREMA escala las instancias de trabajador del consumidor de 0.

Deberías ver los siguientes registros:

Cada mensaje de registro está etiquetado con el componente que lo emitió.

[INFO] [METRIC-PROVIDER] Starting metric collection cycle
[INFO] [METRIC-PROVIDER] Successfully fetched scaled object metrics ...
[INFO] [METRIC-PROVIDER] Sending scale request ...
[INFO] [SCALER] Received ScaleRequest ...
[INFO] [SCALER] Current instances ...
[INFO] [SCALER] Recommended instances ...

También puedes ejecutar el siguiente comando para verificar que el servicio de CREMA recomiende instancias en función de la profundidad de la cola:

gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$CREMA_SERVICE_NAME AND textPayload:SCALER" \
  --limit=20 \
  --format="value(textPayload)" \
  --freshness=5m

Para ver los registros del consumidor que consumen mensajes, ejecuta el siguiente comando:

gcloud beta run worker-pools logs tail $CONSUMER_WORKER_POOL_NAME --region=$REGION

Deberías ver registros que sigan el formato Done job-100.

Limpia

Para evitar cargos adicionales en tu Google Cloud cuenta, borra todos los recursos que implementaste con este instructivo.

Borra el proyecto

Si creaste un proyecto nuevo para este instructivo, bórralo. Si usaste un proyecto existente y necesitas conservarlo sin los cambios que agregaste en este instructivo, borra los recursos que creaste para el instructivo.

La manera más fácil de eliminar la facturación es borrar el proyecto que tú creaste para el instructivo.

Para borrar el proyecto, sigue estos pasos:

  1. En la Google Cloud consola, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que tú quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

Elimina recursos de instructivos

  1. Borra el servicio de Cloud Run que implementaste en este instructivo. Los servicios de Cloud Run no generan costos hasta que reciben solicitudes.

    Para borrar tu servicio de Cloud Run, ejecuta el siguiente comando:

    gcloud run services delete SERVICE-NAME

    Reemplaza SERVICE-NAME por el nombre del servicio.

    También puedes borrar servicios de Cloud Run desde la Google Cloud consola.

  2. Quita la configuración de región predeterminada de gcloud que agregaste durante la configuración en el instructivo:

     gcloud config unset run/region
    
  3. Quita la configuración del proyecto:

     gcloud config unset project
    
  4. Borra los recursos de Pub/Sub:

    gcloud pubsub subscriptions delete $SUBSCRIPTION_ID
    gcloud pubsub topics delete $TOPIC_ID
    
  5. Borra otros Google Cloud recursos que creaste en este instructivo:

¿Qué sigue?