使用 Eventarc 和 Workflows 建立事件導向的自動化調度管理

1. 簡介

f2f35f5c40b91a3c.png c637dcc97f298e7e.png c4a9d5b95f111710.png

Eventarc 可輕鬆將 Cloud Run 服務連結至各種來源的事件。您可以在其中建構事件導向架構,讓微服務鬆耦合且分散。並為您處理事件擷取、傳送、安全防護、授權和錯誤處理工作。

Workflows 是全代管的自動化調度管理平台,可按照您定義的順序 (即工作流程) 執行服務。這些工作流程可以合併 Cloud Run 或 Cloud Functions 代管的服務、Cloud Vision AI 和 BigQuery 等 Google Cloud 服務,以及任何以 HTTP 為基礎的 API。

在本程式碼研究室中,您將建構微服務的事件驅動式協調流程,以處理圖片。您將使用 Workflows 協調 4 個圖片處理 Cloud Functions 的順序、輸入和輸出內容。接著,您將啟用自動化調度管理功能,透過 Eventarc 以鬆散耦合的方式回應 Cloud Storage 事件。

最後,您會獲得彈性但結構化的無伺服器架構,可處理圖片。

b75a14a4268cbe73.png

課程內容

  • Eventarc 和 Workflows 總覽
  • 如何部署 Cloud Functions 服務
  • 如何使用 Workflows 自動化調度管理服務
  • 如何使用 Eventarc 讓 Workflows 回應 Cloud Storage 事件

2. 設定和需求條件

自行設定環境

  1. 登入 Google Cloud 控制台,然後建立新專案或重複使用現有專案。如果沒有 Gmail 或 Google Workspace 帳戶,請先建立帳戶

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

  • 專案名稱是這個專案參與者的顯示名稱。這是 Google API 未使用的字元字串。你隨時可以更新。
  • 專案 ID 在所有 Google Cloud 專案中都是不重複的,而且設定後即無法變更。Cloud 控制台會自動產生專屬字串,通常您不需要理會該字串。在大多數程式碼研究室中,您需要參照專案 ID (通常標示為 PROJECT_ID)。如果您不喜歡產生的 ID,可以產生另一個隨機 ID。你也可以嘗試使用自己的名稱,看看是否可用。完成這個步驟後就無法變更,且專案期間會維持不變。
  • 請注意,有些 API 會使用第三個值,也就是「專案編號」。如要進一步瞭解這三種值,請參閱說明文件
  1. 接著,您需要在 Cloud 控制台中啟用帳單,才能使用 Cloud 資源/API。完成這個程式碼研究室的費用不高,甚至可能完全免費。如要關閉資源,避免在本教學課程結束後繼續產生費用,您可以刪除建立的資源或專案。Google Cloud 新使用者可參加價值$300 美元的免費試用計畫。

啟動 Cloud Shell

雖然您可以透過筆電遠端操作 Google Cloud,但在本程式碼研究室中,您將使用 Google Cloud Shell,這是可在雲端執行的指令列環境。

Google Cloud 控制台中,點選右上角工具列的 Cloud Shell 圖示:

啟用 Cloud Shell

佈建並連線至環境的作業需要一些時間才能完成。完成後,您應該會看到如下的內容:

Google Cloud Shell 終端機的螢幕截圖,顯示環境已連線

這部虛擬機器搭載各種您需要的開發工具,並提供永久的 5GB 主目錄,而且在 Google Cloud 運作,能大幅提升網路效能並強化驗證功能。您可以在瀏覽器中完成本程式碼研究室的所有作業。您不需要安裝任何軟體。

設定 gcloud

在 Cloud Shell 中,設定專案 ID 和要部署應用程式的區域。分別儲存為 PROJECT_IDREGION 變數。如需可用區域,請參閱「Cloud Functions 區域」。

PROJECT_ID=your-project-id
gcloud config set project $PROJECT_ID

取得原始碼

應用程式的原始碼位於 eventarc-samples 存放區的 processing-pipelines 資料夾中。

複製存放區:

git clone https://github.com/GoogleCloudPlatform/eventarc-samples.git

前往 eventarc-samples/processing-pipelines 資料夾:

cd eventarc-samples/processing-pipelines

3. 架構總覽

應用程式架構如下:

7b810e1505054c0c.png

  1. 將圖片儲存至輸入 bucket,產生 Cloud Storage 建立事件。
  2. Eventarc 會透過 Cloud Storage 觸發條件讀取 Cloud Storage 建立事件,並以 CloudEvent 形式傳遞至 Workflows
  3. 在工作流程的第一個步驟「篩選」中,Cloud Functions 服務會使用 Vision API 判斷圖片是否安全。如果圖片安全無虞,工作流程會繼續執行後續步驟。
  4. 在工作流程的第二個步驟中,Cloud Functions 服務「Labeler」會使用 Vision API 擷取圖片的標籤,並將標籤儲存至輸出 bucket。
  5. 在第三個步驟中,另一個 Cloud Functions 服務「Resizer」會使用 ImageSharp 調整圖片大小,並將調整後的圖片儲存至輸出 bucket。
  6. 最後一個步驟是 Watermarker,這是另一個 Cloud Functions 服務,會使用 ImageSharp 將 Labeler 的標籤浮水印新增至調整大小後的圖片,並將圖片儲存至輸出 bucket。

應用程式是由 Cloud Storage 事件觸發,因此屬於事件導向。圖片處理作業會在工作流程中進行,因此屬於協調作業。最終,這項服務會成為事件導向的自動化調度管理服務,以靈活但結構化的無伺服器架構處理圖片。

4. 建立 bucket

建立輸入 bucket,供使用者上傳圖片;建立輸出 bucket,供圖片處理管道儲存處理後的圖片。

在 Cloud Shell 中執行下列指令:

REGION=us-central1
BUCKET1=$PROJECT_ID-images-input-$RANDOM
BUCKET2=$PROJECT_ID-images-output-$RANDOM

gsutil mb -l $REGION gs://$BUCKET1
gsutil mb -l $REGION gs://$BUCKET2

5. 部署篩選器服務

首先部署第一個服務。這項 Cloud Functions 服務會接收 bucket 和檔案資訊,使用 Vision API 判斷圖片是否安全,然後傳回結果。

首先,請為 Cloud Functions 第 2 代和 Vision API 啟用必要服務:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  cloudfunctions.googleapis.com \
  run.googleapis.com \
  vision.googleapis.com

在頂層 processing-pipelines 資料夾中部署服務:

SERVICE_NAME=filter

gcloud functions deploy $SERVICE_NAME \
  --gen2 \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --entry-point Filter.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v3/filter/csharp

函式部署完畢後,請在變數中設定服務網址,稍後會用到:

FILTER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')

6. 部署標籤服務

第二個 Cloud Functions 服務會接收 bucket 和檔案資訊,使用 Vision API 擷取圖片的標籤,並將標籤儲存至輸出 bucket。

在頂層 processing-pipelines 資料夾中部署服務:

SERVICE_NAME=labeler

gcloud functions deploy $SERVICE_NAME \
  --gen2 \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --set-env-vars BUCKET=$BUCKET2 \
  --entry-point Labeler.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v2/labeler/csharp

函式部署完畢後,請在變數中設定服務網址,稍後會用到:

LABELER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')

7. 部署調整大小服務

這項 Cloud Functions 服務會接收 bucket 和檔案資訊,使用 ImageSharp 調整圖片大小,然後將圖片儲存至輸出 bucket。

在頂層 processing-pipelines 資料夾中部署服務:

SERVICE_NAME=resizer

gcloud functions deploy $SERVICE_NAME \
  --gen2 \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --set-env-vars BUCKET=$BUCKET2 \
  --entry-point Resizer.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v2/resizer/csharp \
  --timeout=120s

請注意 2 分鐘的 timeout 值,讓調整大小函式有額外時間處理。

函式部署完畢後,請在變數中設定服務網址,稍後會用到:

RESIZER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')

8. 部署浮水印服務

這項 Cloud Functions 服務會接收 bucket、檔案和標籤資訊,讀取檔案,使用 ImageSharp 將標籤新增為圖片浮水印,然後將圖片儲存至輸出 bucket。

在頂層 processing-pipelines 資料夾中部署服務:

SERVICE_NAME=watermarker

gcloud functions deploy $SERVICE_NAME \
  --gen2 \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --set-env-vars BUCKET=$BUCKET2 \
  --entry-point Watermarker.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v2/watermarker/csharp

函式部署完畢後,請在變數中設定服務網址,稍後會用到:

WATERMARKER_URL=$(gcloud functions describe $SERVICE_NAME --region=$REGION --gen2 --format 'value(serviceConfig.uri)')

此時,所有四個 Cloud Functions 應已部署並執行:

fe662925cb0121e9.png

9. 定義及部署工作流程

使用 Workflows 將篩選器、標籤人員、調整大小和浮水印服務整合至工作流程。Workflows 會按照我們定義的順序和參數,自動化調度管理這些服務的呼叫作業。

首先,請為 Workflows 啟用必要服務:

gcloud services enable \
  workflows.googleapis.com \
  workflowexecutions.googleapis.com

定義

工作流程會將 CloudEvent 做為參數。建立觸發條件後,Eventarc 會提供這項資訊。在前兩個步驟中,工作流程會記錄事件,並從事件中擷取儲存區和檔案資訊:

main:
  params: [event]
  steps:
  - log_event:
      call: sys.log
      args:
          text: ${event}
          severity: INFO
  - extract_bucket_and_file:
      assign:
      - bucket: ${event.data.bucket}
      - file: ${event.data.name}

filter 步驟中,Workflows 會呼叫我們先前部署的篩選器服務。接著,系統會記錄並檢查檔案安全性:

  - filter:
      call: http.post
      args:
        url: FILTER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${bucket}
            file: ${file}
      result: filterResponse
  - log_safety:
      call: sys.log
      args:
          text: ${filterResponse.body.safe}
          severity: INFO
  - check_safety:
      switch:
        - condition: ${filterResponse.body.safe == true}
          next: label
      next: end

label 步驟中,Workflows 會呼叫標籤服務並擷取回應 (前 3 個標籤):

  - label:
      call: http.post
      args:
        url: LABELER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${bucket}
            file: ${file}
      result: labelResponse

resize 步驟中,Workflows 會呼叫調整大小服務並擷取回應 (調整大小後的圖片的 bucket 和檔案):

  - resize:
      call: http.post
      args:
        url: RESIZER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${bucket}
            file: ${file}
      result: resizeResponse

watermark 步驟中,工作流程會使用調整大小後的圖片和標籤呼叫浮水印服務,並擷取結果 (調整大小並加上浮水印的圖片):

  - watermark:
      call: http.post
      args:
        url: WATERMARKER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${resizeResponse.body.bucket}
            file: ${resizeResponse.body.file}
            labels: ${labelResponse.body.labels}
      result: watermarkResponse

final 步驟中,Workflows 會從標籤器、調整大小器和浮水印服務傳回 HTTP 狀態碼:

  - final:
      return:
        label: ${labelResponse.code}
        resize: ${resizeResponse.code}
        watermark: ${watermarkResponse.code}

部署

部署工作流程前,請務必手動或使用 sed,將服務網址替換為已部署函式的網址:

在頂層 processing-pipelines 資料夾中,前往 image-v3 資料夾 (workflows.yaml 檔案所在位置):

cd image-v3/

執行 sed,將預留位置網址替換為已部署服務的實際網址:

sed -i -e "s|FILTER_URL|${FILTER_URL}|" workflow.yaml
sed -i -e "s|LABELER_URL|${LABELER_URL}|" workflow.yaml
sed -i -e "s|RESIZER_URL|${RESIZER_URL}|" workflow.yaml
sed -i -e "s|WATERMARKER_URL|${WATERMARKER_URL}|" workflow.yaml

部署工作流程:

WORKFLOW_NAME=image-processing

gcloud workflows deploy $WORKFLOW_NAME \
    --source=workflow.yaml \
    --location=$REGION

幾秒後,您應該會在控制台中看到已部署的工作流程:

a5f537f2b3f3bd3.png

10. 建立觸發條件

工作流程部署完成後,最後一個步驟是透過 Eventarc 觸發條件,將工作流程連結至 Cloud Storage 事件。

一次性設定

首先,請為 Eventarc 啟用必要服務:

gcloud services enable \
 eventarc.googleapis.com

建立要在 Eventarc 觸發條件中使用的服務帳戶。

SERVICE_ACCOUNT=eventarc-trigger-imageproc-sa

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Eventarc trigger image processing service account"

授予 workflows.invoker 角色,以便使用服務帳戶從 Eventarc 叫用 Workflows:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --role roles/workflows.invoker \
  --member serviceAccount:$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

eventarc.eventReceiver 角色指派給服務帳戶,以便在

Cloud Storage 觸發條件:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --role roles/eventarc.eventReceiver \
  --member serviceAccount:$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

pubsub.publisher 角色授予 Cloud Storage 服務帳戶。Eventarc 的 Cloud Storage 觸發條件需要這項設定:

STORAGE_SERVICE_ACCOUNT="$(gsutil kms serviceaccount -p $PROJECT_ID)"

gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member serviceAccount:$STORAGE_SERVICE_ACCOUNT \
    --role roles/pubsub.publisher

建立

執行下列指令來建立觸發條件。這個觸發條件會篩選輸入 Cloud Storage bucket 中的新檔案建立事件,並將這些事件傳遞至先前定義的工作流程:

TRIGGER_NAME=trigger-image-processing

gcloud eventarc triggers create $TRIGGER_NAME \
  --location=$REGION \
  --destination-workflow=$WORKFLOW_NAME \
  --destination-workflow-location=$REGION \
  --event-filters="type=google.cloud.storage.object.v1.finalized" \
  --event-filters="bucket=$BUCKET1" \
  --service-account=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

您可以在 Cloud 控制台的 Eventarc 部分看到觸發條件已建立並準備就緒:

a5f4301863d7d9e4.png

11. 測試管道

圖片處理管道已準備好接收 Cloud Storage 中的事件。如要測試管道,請將圖片上傳至輸入 bucket:

gsutil cp beach.jpg gs://$BUCKET1

上傳圖片後,您應該會看到工作流程執行作業處於有效狀態:

2c914341950b5fde.png

大約一分鐘後,您應該會看到執行成功。您也可以查看工作流程的輸入和輸出內容:

9abba6c28c51a9b5.png

列出輸出 bucket 的內容時,您應該會看到調整大小後的圖片、調整大小並加上浮水印的圖片,以及圖片的標籤:

gsutil ls gs://$BUCKET2

gs://$PROJECT_ID-images-output-$RANDOM/beach-400x400-watermark.jpeg
gs://$PROJECT_ID-images-output-$RANDOM/beach-400x400.png
gs://$PROJECT_ID-images-output-$RANDOM/beach-labels.txt

如要再次確認,可以開啟已調整大小並加上浮水印的圖片,查看結果:

46d375cb05a8aae4.jpeg

12. 恭喜

恭喜,您已完成本程式碼研究室!

涵蓋內容

  • Eventarc 和 Workflows 總覽
  • 如何部署 Cloud Functions 服務
  • 如何使用 Workflows 自動化調度管理服務
  • 如何使用 Eventarc 讓 Workflows 回應 Cloud Storage 事件