根據 Pub/Sub 佇列量自動調度工作站集區資源

本教學課程說明如何部署 Cloud Run 工作站集區來處理 Pub/Sub 訊息,並使用 Cloud Run 外部指標自動調度資源 (CREMA),根據佇列深度自動調整消費者執行個體。

目標

在這個教學課程中,您將執行下列操作:

費用

在本文件中,您會使用下列 Google Cloud的計費元件:

如要根據預測用量估算費用,請使用 Pricing Calculator

初次使用 Google Cloud 的使用者可能符合免費試用期資格。

事前準備

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  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. 啟用 Cloud Run、Parameter Manager、Artifact Registry、Pub/Sub 和 Cloud Build API。

    啟用 API 時所需的角色

    如要啟用 API,您需要服務使用情形管理員 IAM 角色 (roles/serviceusage.serviceUsageAdmin),其中包含 serviceusage.services.enable 權限。瞭解如何授予角色

    啟用 API

  7. 安裝並初始化 gcloud CLI
  8. 更新元件:
    gcloud components update
  9. 本教學課程會使用多個環境變數。如要改善偵錯作業,請執行下列指令,在您參照未設定的本機環境變數時產生錯誤:
    set -u
  10. 設定本教學課程中使用的 CREMA 相關設定變數:
    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
    PROJECT_ID 替換為專案 ID。 Google Cloud
  11. 執行下列指令來設定專案 ID:
    gcloud config set project $PROJECT_ID
  12. 系統會根據您觸發資源調度的頻率,收取 Cloud Run 資源調度服務的費用。如要瞭解詳情,請使用定價計算機估算費用。

必要的角色

如要取得完成本教學課程所需的權限,請要求管理員在專案中授予您下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

您或許也能透過自訂角色或其他預先定義的角色,取得必要權限。

建立 Pub/Sub 主題和訂閱項目

如要自動調度工作站資源,請按照下列步驟,為消費者應用程式建立提取訂閱項目:

  1. 建立代表訊息動態消息的 Pub/Sub 主題:

    gcloud pubsub topics create $TOPIC_ID
    
  2. 建立提取訂閱項目,從 Pub/Sub 主題取用訊息:

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

建立自訂服務帳戶

本教學課程需要下列兩個服務帳戶,且具備使用已佈建資源時所需的最低權限

  • 消費者服務帳戶:處理訊息的消費者工作站集區身分。執行下列指令,建立消費者服務帳戶:

    gcloud iam service-accounts create $CONSUMER_SA_NAME \
      --display-name="Pub/Sub consumer service account"
    
  • CREMA 服務帳戶:自動配置器的身分。執行下列指令,建立 CREMA 服務帳戶:

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

將其他權限授予自訂服務帳戶

如要調整工作站集區大小,請在自訂服務帳戶中授予下列權限:

  1. 授予 CREMA 服務帳戶從 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. 授予 CREMA 服務帳戶擴縮工作站集區的權限:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/run.developer"
    
  3. 將服務帳戶使用者角色授予 CREMA 服務帳戶:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/iam.serviceAccountUser"
    
  4. 授予 CREMA 服務帳戶權限,以查看指標:

     gcloud projects add-iam-policy-binding $PROJECT_ID \
       --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
       --role="roles/monitoring.viewer"
    
  5. 授予 CREMA 服務帳戶寫入指標的權限:

     gcloud projects add-iam-policy-binding $PROJECT_ID \
       --member="serviceAccount:$CREMA_SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
       --role="roles/monitoring.metricWriter"
    
  6. 授予 CREMA 服務帳戶查看 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. 授予取用者服務帳戶從訂閱項目提取訊息的權限:

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

部署 Cloud Run worker 集區

如要部署工作站集區,從 Pub/Sub 訂閱項目取用訊息,請按照下列步驟操作:

  1. 建立名為 consumer 的資料夾,然後將目錄變更為該資料夾:

    mkdir consumer
    cd consumer
    
  2. 建立名為 worker.py 的檔案,並加入下列程式碼:

    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. 建立 Dockerfile 並加入下列程式碼:

    FROM python:3.12-slim
    RUN pip install google-cloud-pubsub
    COPY worker.py .
    CMD ["python", "-u", "worker.py"]
    
  4. 部署執行個體數為 0 的消費者工作站集區,供 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
    

部署自動配置器 CREMA 服務

將工作站集區部署完畢,開始從 Pub/Sub 接收訊息後,請設定 CREMA 自動配置器,根據訊息量佈建工作站執行個體。

設定自動配置器

本教學課程使用Parameter Manager儲存 CREMA 的 YAML 設定檔。

  1. 在 Parameter Manager 中建立參數,儲存 CREMA 的參數版本:

    PARAMETER_ID=crema-config
    PARAMETER_REGION=global
    gcloud parametermanager parameters create $PARAMETER_ID --location=$PARAMETER_REGION --parameter-format=YAML
    
  2. 執行下列指令,前往專案的根目錄:

    cd
    
  3. 在根目錄中建立 YAML 檔案 my-crema-config.yaml,定義自動配置器設定:

    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
    

    PROJECT_ID 替換為 Google Cloud 專案 ID。

  4. 上傳本機 YAML 檔案做為新的參數版本:

    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. 執行下列指令,確認參數是否已成功新增:

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

    畫面上應該會顯示參數路徑,例如 projects/PROJECT_ID/locations/global/parameters/crema-config/versions/1

部署服務來調度工作負載資源

如要部署服務來調整工作站集區的資源配置,請使用預先建構的容器映像檔執行下列指令:

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"

測試自動調度資源服務

建立指令碼,產生 100 則訊息並推送至 Pub/Sub 佇列,藉此測試 CREMA 服務:

  1. 在根目錄中,建立名為 load-pubsub.sh 的檔案,並加入下列程式碼:

    #!/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. 執行負載測試:

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

這個指令會產生 100 則訊息,並推送至 Pub/Sub 訂閱項目。

監控縮放作業

load-pubsub.sh 指令碼完成後,請等待 3 到 4 分鐘,再檢查服務的記錄 my-crema-service。CREMA 自動配置器服務會將取用端 worker 執行個體從 0 擴充。

您應該會看到下列記錄:

每則記錄訊息都會標示發出訊息的元件。

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

或者,您也可以執行下列指令,確認 CREMA 服務是否根據佇列深度建議執行個體:

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

如要查看取用訊息的消費者記錄,請執行下列指令:

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

您應該會看到符合 Done job-100 格式的記錄。

清除所用資源

為避免系統向您的 Google Cloud 帳戶收取額外費用,請刪除您在本教學課程中部署的所有資源。

刪除專案

如果您是為了這個教學課程建立新專案,請刪除該專案。如果您使用現有專案,並想保留專案,但不要本教學課程新增的變更,請刪除為本教學課程建立的資源

如要避免付費,最簡單的方法就是刪除您為了本教學課程所建立的專案。

刪除專案的方法如下:

  1. 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。

    前往「Manage resources」(管理資源)

  2. 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)
  3. 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。

刪除教學課程資源

  1. 刪除您在本教學課程中部署的 Cloud Run 服務。Cloud Run 服務收到要求後才會開始計費。

    如要刪除 Cloud Run 服務,請執行下列指令:

    gcloud run services delete SERVICE-NAME

    SERVICE-NAME 改為您的服務名稱。

    您也可以從Google Cloud 控制台刪除 Cloud Run 服務。

  2. 移除您在教學課程設定期間新增的 gcloud 預設區域設定:

     gcloud config unset run/region
    
  3. 移除專案設定:

     gcloud config unset project
    
  4. 刪除 Pub/Sub 資源:

    gcloud pubsub subscriptions delete $SUBSCRIPTION_ID
    gcloud pubsub topics delete $TOPIC_ID
    
  5. 刪除在本教學課程中建立的其他 Google Cloud 資源:

後續步驟