Scalabilità automatica dei pool di worker in base al volume della coda Pub/Sub

Questo tutorial mostra come eseguire il deployment di un pool di worker Cloud Run per elaborare i messaggi Pub/Sub e scalare automaticamente le istanze consumer in base alla profondità della coda utilizzando la scalabilità automatica delle metriche esterne di Cloud Run (CREMA).

Obiettivi

In questo tutorial, imparerai a:

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

I nuovi Google Cloud utenti potrebbero avere diritto a una prova senza costi.

Prima di iniziare

  1. Accedi al tuo Google Cloud account. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti senza costi per l'esecuzione, il test e il deployment dei workload.
  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. Abilita le API Cloud Run, Parameter Manager, Artifact Registry, Pub/Sub e Cloud Build.

    Ruoli richiesti per abilitare le API

    Per abilitare le API, devi disporre del ruolo IAM Amministratore Service Usage (roles/serviceusage.serviceUsageAdmin), che contiene l'autorizzazione serviceusage.services.enable. Scopri come concedere i ruoli.

    Abilita le API

  7. Installa e inizializza gcloud CLI.
  8. Aggiorna i componenti:
    gcloud components update
  9. Questo tutorial utilizza diverse variabili di ambiente. Per migliorare il debug, esegui il comando seguente per generare un errore quando fai riferimento a variabili di ambiente locali non impostate:
    set -u
  10. Imposta le seguenti variabili di configurazione per CREMA utilizzate in questo tutorial:
    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
    Sostituisci PROJECT_ID con l'ID del tuo Google Cloud progetto.
  11. Imposta l'ID progetto eseguendo il comando seguente:
    gcloud config set project $PROJECT_ID
  12. Ti vengono addebitati costi per il servizio di scalabilità di Cloud Run in base alla frequenza con cui attivi la scalabilità. Per ulteriori informazioni, stima i costi con il calcolatore prezzi.

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per completare il tutorial, chiedi all'amministratore di concederti i seguenti ruoli IAM nel progetto:

Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.

Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

Crea un argomento e una sottoscrizione Pub/Sub

Per scalare automaticamente il worker, crea una sottoscrizione pull per l'applicazione consumer seguendo questi passaggi:

  1. Crea un argomento Pub/Sub che rappresenti un feed di messaggi:

    gcloud pubsub topics create $TOPIC_ID
    
  2. Crea una sottoscrizione pull per utilizzare i messaggi dall'argomento Pub/Sub:

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

Crea account di servizio personalizzati

Questo tutorial richiede i seguenti due account di servizio con le autorizzazioni minime necessarie per utilizzare le risorse di cui è stato eseguito il provisioning:

  • Account di servizio consumer: identità per il pool di worker consumer che elabora i messaggi. Esegui il comando seguente per creare l'account di servizio consumer:

    gcloud iam service-accounts create $CONSUMER_SA_NAME \
      --display-name="Pub/Sub consumer service account"
    
  • Account di servizio CREMA: identità per il gestore della scalabilità automatica. Esegui il comando seguente per creare l'account di servizio CREMA:

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

Concedi autorizzazioni aggiuntive ai tuoi account di servizio personalizzati

Per scalare il pool di worker, concedi le seguenti autorizzazioni sugli account di servizio personalizzati:

  1. Concedi all'account di servizio CREMA l'autorizzazione per leggere da 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. Concedi all'account di servizio CREMA l'autorizzazione per scalare il pool di worker:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/run.developer"
    
  3. Concedi all'account di servizio CREMA il ruolo Utente account di servizio:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/iam.serviceAccountUser"
    
  4. Concedi all'account di servizio CREMA l'autorizzazione per visualizzare le metriche:

     gcloud projects add-iam-policy-binding $PROJECT_ID \
       --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
       --role="roles/monitoring.viewer"
    
  5. Concedi all'account di servizio CREMA l'autorizzazione per scrivere le metriche:

     gcloud projects add-iam-policy-binding $PROJECT_ID \
       --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
       --role="roles/monitoring.metricWriter"
    
  6. Concedi all'account di servizio CREMA l'autorizzazione per visualizzare i messaggi 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. Concedi all'account di servizio consumer l'autorizzazione per eseguire il pull dei messaggi dalla sottoscrizione:

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

Esegui il deployment di un pool di worker Cloud Run

Per eseguire il deployment di un pool di worker che utilizza i messaggi dalle sottoscrizioni Pub/Sub:

  1. Crea una cartella denominata consumer e cambia la directory in questa cartella:

    mkdir consumer
    cd consumer
    
  2. Crea un file denominato worker.py e aggiungi il codice seguente:

    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 e aggiungi il codice seguente:

    FROM python:3.12-slim
    RUN pip install google-cloud-pubsub
    COPY worker.py .
    CMD ["python", "-u", "worker.py"]
    
  4. Esegui il deployment del pool di worker consumer con 0 istanze per fare lo scale up di CREMA:

    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
    

Esegui il deployment del servizio di scalabilità automatica CREMA

Dopo aver eseguito il deployment del pool di worker per utilizzare i messaggi da Pub/Sub, configura il gestore della scalabilità automatica CREMA per eseguire il provisioning delle istanze worker in base al volume dei messaggi.

Configura il gestore della scalabilità automatica

Questo tutorial utilizza il Parameter Manager per archiviare il file di configurazione YAML per CREMA.

  1. Crea un parametro in Parameter Manager per archiviare le versioni dei parametri per CREMA:

    PARAMETER_ID=crema-config
    PARAMETER_REGION=global
    gcloud parametermanager parameters create $PARAMETER_ID --location=$PARAMETER_REGION --parameter-format=YAML
    
  2. Passa alla directory principale del progetto eseguendo il comando seguente:

    cd
    
  3. Nella directory principale, crea un file YAML, my-crema-config.yaml, per definire la configurazione del gestore della scalabilità automatica:

    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
    

    Sostituisci PROJECT_ID con l' Google Cloud ID progetto.

  4. Carica il file YAML locale come nuova versione del parametro:

    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. Esegui il comando seguente per verificare che l'aggiunta del parametro sia andata a buon fine:

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

    Dovresti visualizzare il percorso del parametro, ad esempio projects/PROJECT_ID/locations/global/parameters/crema-config/versions/1.

Esegui il deployment del servizio per scalare i workload

Per eseguire il deployment del servizio per scalare il pool di worker, esegui il comando seguente con un'immagine container predefinita:

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"

Testa il servizio di scalabilità automatica

Testa il servizio CREMA creando uno script che genera 100 messaggi ed esegue il push nella coda Pub/Sub:

  1. Nella directory principale, crea un file denominato load-pubsub.sh e aggiungi il codice seguente:

    #!/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. Esegui il test di carico:

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

Questo comando genera ed esegue il push di 100 messaggi nella sottoscrizione Pub/Sub.

Monitora la scalabilità

Al termine dello script load-pubsub.sh, attendi tre o quattro minuti prima di controllare i log del servizio my-crema-service. Il servizio di scalabilità automatica CREMA aumenta il numero di istanze worker consumer da 0.

Dovresti visualizzare i seguenti log:

Ogni messaggio di log è etichettato con il componente che lo ha emesso.

[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 ...

In alternativa, esegui il comando seguente per verificare che il servizio CREMA consigli le istanze in base alla profondità della coda:

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

Per visualizzare i log consumer che utilizzano i messaggi, esegui il comando seguente:

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

Dovresti visualizzare i log nel formato Done job-100.

Libera spazio

Per evitare addebiti aggiuntivi al tuo Google Cloud account, elimina tutte le risorse di cui hai eseguito il deployment con questo tutorial.

Elimina il progetto

Se hai creato un nuovo progetto per questo tutorial, eliminalo. Se hai utilizzato un progetto esistente e devi conservarlo senza le modifiche aggiunte in questo tutorial, elimina le risorse create per il tutorial.

Il modo più semplice per eliminare la fatturazione è eliminare il progetto che hai creato per il tutorial.

Per eliminare il progetto:

  1. Nella Google Cloud console, vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID progetto e fai clic su Chiudi per eliminare il progetto.

Elimina le risorse del tutorial

  1. Elimina il servizio Cloud Run di cui hai eseguito il deployment in questo tutorial. I servizi Cloud Run non comportano costi finché non ricevono richieste.

    Per eliminare il servizio Cloud Run, esegui il comando seguente:

    gcloud run services delete SERVICE-NAME

    Sostituisci SERVICE-NAME con il nome del tuo servizio.

    Puoi eliminare i servizi Cloud Run anche dalla Google Cloud console.

  2. Rimuovi la configurazione della regione predefinita di gcloud che hai aggiunto durante la configurazione del tutorial:

     gcloud config unset run/region
    
  3. Rimuovi la configurazione del progetto:

     gcloud config unset project
    
  4. Elimina le risorse Pub/Sub:

    gcloud pubsub subscriptions delete $SUBSCRIPTION_ID
    gcloud pubsub topics delete $TOPIC_ID
    
  5. Elimina le altre Google Cloud risorse create in questo tutorial:

Passaggi successivi