Workflows 無伺服器自動化調度管理簡介

使用 Workflows 進行無伺服器自動化調度管理簡介

程式碼研究室簡介

subject上次更新時間:3月 19, 2025
account_circle作者:atamel

1. 簡介

c9b0cc839df0bb8f.png

您可以使用 Workflows 建立無伺服器工作流程,按照您定義的順序連結一系列無伺服器工作。您可以結合 Google Cloud 的 API、Cloud Functions 和 Cloud Run 等無伺服器產品,以及外部 API 的呼叫,藉此建構彈性的無伺服器應用程式。

Workflows 不需管理基礎架構,並能視需求順暢調度資源,甚至將資源縮減至零。採用「以量計價,即付即用」的定價模式,因此您只需要為執行時間付費。

在本程式碼研究室中,您將瞭解如何將各種 Google Cloud 服務和外部 HTTP API 連結至工作流程。具體來說,您將連結兩個公開 Cloud Functions 服務、一個私人 Cloud Run 服務和外部公開 HTTP API 至工作流程。

課程內容

  • 工作流程的基本概念。
  • 如何將公開 Cloud Functions 連結至工作流程。
  • 如何將私人 Cloud Run 服務連結至工作流程。
  • 如何將外部 HTTP API 連結至 Workflow。

2. 設定和需求

自助式環境設定

  1. 登入 Cloud 控制台,然後建立新專案或重複使用現有專案。(如果您還沒有 Gmail 或 G Suite 帳戶,請務必建立帳戶)。

H_hgylo4zxOllHaAbPKJ7VyqCKPDUnDhkr-BsBIFBsrB6TYSisg6LX-uqmMhh4sXUy_hoa2Qv87C2nFmkg-QAcCiZZp0qtpf6VPaNEEfP_iqt29KVLD-gklBWugQVeOWsFnJmNjHDw

dcCPqfBIwNO4R-0fNQLUC4aYXOOZhKhjUnakFLZJGeziw2ikOxGjGkCHDwN5x5kCbPFB8fiOzZnX-GfuzQ8Ox-UU15BwHirkVPR_0RJwl0oXrhqZmMIvZMa_uwHugBJIdx5-bZ6Z8Q

jgLzVCxk93d6E2bbonzATKA4jFZReoQ-fORxZZLEi5C3D-ubnv6nL-eP-iyh7qAsWyq_nyzzuEoPFD1wFOFZOe4FWhPBJjUDncnTxTImT3Ts9TM54f4nPpsAp52O0y3Cb19IceAEgQ

請記住專案 ID,這是所有 Google Cloud 專案的專屬名稱 (上述名稱已被使用,因此無法使用)。這個值稍後會在本程式碼研究室中稱為 PROJECT_ID

  1. 接著,您需要在 Cloud 控制台中啟用帳單功能,才能使用 Google Cloud 資源。

執行本程式碼研究室時,費用應該不會太高,請務必按照「清除」一節中的操作說明,瞭解如何關閉資源,避免產生教學課程以外的帳單費用。Google Cloud 新使用者可享有 $300 美元的免費試用期

啟動 Cloud Shell

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

在 GCP 主控台的右上方工具列中,按一下 Cloud Shell 圖示:

STgwiN06Y0s_gL7i9bTed8duc9tWOIaFw0z_4QOjc-jeOmuH2TBK8l4udei56CKPLoM_i1yEF6pn5Ga88eniJQoEh8cAiTH79gWUHJdKOw0oiBZfBpOdcEOl6p29i4mvPe_A6UMJBQ

佈建並連線至環境的作業需要一些時間才能完成。完成後,畫面應如下所示:

r6WRHJDzL-GdB5VDxMWa67_cQxRR_x_xCG5xdt9Nilfuwe9fTGAwM9XSZbNPWvDSFtrZ7DDecKqR5_pIq2IJJ9puAMkC3Kt4JbN9jfMX3gAwTNHNqFmqOJ-3iIX5HSePO4dNVZUkNA

這個虛擬機器會載入您需要的所有開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,可大幅提升網路效能和驗證功能。您只需使用瀏覽器,就能完成本研究室中的所有工作。

3. 工作流程總覽

基本資訊

工作流程由一系列步驟組成,這些步驟是以 Workflows 的 YAML 語法描述。這是工作流程的定義。如需 Workflows YAML 語法的詳細說明,請參閱「語法參考資料」頁面。

建立工作流程後,系統會部署工作流程,讓工作流程準備就緒,以便執行。執行作業是指工作流程定義中邏輯的單次執行作業。所有工作流程執行作業都是獨立的,且產品可支援大量並行執行作業。

啟用服務

在本程式碼研究室中,您將連結 Cloud Functions 和 Cloud Run 服務,並與工作流程整合。您也會在建構服務時使用 Cloud Build 和 Cloud Storage。

啟用所有必要服務:

gcloud services enable \
  cloudfunctions.googleapis.com \
  run.googleapis.com \
  workflows.googleapis.com \
  cloudbuild.googleapis.com \
  storage.googleapis.com

在下一個步驟中,您將在工作流程中連結兩個 Cloud Functions。

4. 部署第一個 Cloud 函式

第一個函式是 Python 中的隨機數字產生器。

建立函式程式碼的目錄並前往該目錄:

mkdir ~/randomgen
cd ~/randomgen

在目錄中建立含有以下內容的 main.py 檔案:

import random, json
from flask import jsonify

def randomgen(request):
    randomNum = random.randint(1,100)
    output = {"random":randomNum}
    return jsonify(output)

收到 HTTP 要求時,這個函式會產生介於 1 和 100 之間的隨機數字,並以 JSON 格式傳回給呼叫端。

這個函式會使用 Flask 處理 HTTP,因此我們需要將 Flask 新增為依附元件。Python 中的依附元件由 pip 代管,並以名為 requirements.txt 的中繼資料檔案表示。

在同一個目錄中建立含有以下內容的 requirements.txt 檔案:

flask>=1.0.2

使用這項指令,部署具備 HTTP 觸發條件且允許未經驗證要求的函式:

gcloud functions deploy randomgen \
    --runtime python312 \
    --trigger-http \
    --allow-unauthenticated

函式部署完成後,您可以在主控台或透過 gcloud functions describe 指令,查看 url 屬性下方顯示的函式網址。

您也可以使用下列 curl 指令,前往函式的網址:

curl $(gcloud functions describe randomgen --format='value(url)')

函式已準備好用於工作流程。

5. 部署第二個 Cloud 函式

第二個函式是乘數。會將收到的輸入值乘以 2。

建立函式程式碼的目錄並前往該目錄:

mkdir ~/multiply
cd ~/multiply

在目錄中建立含有以下內容的 main.py 檔案:

import random, json
from flask import jsonify

def multiply(request):
    request_json = request.get_json()
    output = {"multiplied":2*request_json['input']}
    return jsonify(output)

收到 HTTP 要求時,這個函式會從 JSON 主體擷取 input,並將其乘以 2,然後以 JSON 格式傳回給呼叫端。

在同一個目錄中建立相同的 requirements.txt 檔案,並加入以下內容:

flask>=1.0.2

使用這項指令,部署具備 HTTP 觸發條件且允許未經驗證要求的函式:

gcloud functions deploy multiply \
    --runtime python312 \
    --trigger-http \
    --allow-unauthenticated

函式部署完成後,您也可以使用下列 curl 指令,前往函式的網址:

curl $(gcloud functions describe multiply --format='value(url)') \
-X POST \
-H "content-type: application/json" \
-d '{"input": 5}'

函式已準備好用於工作流程。

6. 連結兩個 Cloud 函式

在第一個工作流程中,將這兩個函式連結在一起。

建立含有以下內容的 workflow.yaml 檔案。

- randomgenFunction:
    call: http.get
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/randomgen
    result: randomgenResult
- multiplyFunction:
    call: http.post
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/multiply
        body:
            input: ${randomgenResult.body.random}
    result: multiplyResult
- returnResult:
    return: ${multiplyResult}

在這個工作流程中,您會從第一個函式取得隨機數字,並將該數字傳遞至第二個函式。結果就是相乘的隨機數字。

部署第一個工作流程:

gcloud workflows deploy workflow --source=workflow.yaml

執行第一個工作流程:

gcloud workflows execute workflow

工作流程執行完畢後,您可以傳入上一個步驟提供的執行 ID,查看結果:

gcloud workflows executions describe <your-execution-id> --workflow workflow

輸出內容會包含 resultstate

result: '{"body":{"multiplied":108},"code":200 ... } 

...
state: SUCCEEDED

7. 連結外部 HTTP API

接下來,您將在工作流程中將 math.js 連結為外部服務。

math.js 中,您可以評估以下類型的數學運算式:

curl https://api.mathjs.org/v4/?'expr=log(56)'

這次您將使用 Cloud 控制台更新工作流程。在 Google Cloud 控制台中找出 Workflows

7608a7991b33bbb0.png

找出工作流程,然後按一下「Definition」分頁:

f3c8c4d3ffa49b1b.png

編輯工作流程定義,並加入對 math.js 的呼叫。

- randomgenFunction:
    call: http.get
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/randomgen
    result: randomgenResult
- multiplyFunction:
    call: http.post
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/multiply
        body:
            input: ${randomgenResult.body.random}
    result: multiplyResult
- logFunction:
    call: http.get
    args:
        url: https://api.mathjs.org/v4/
        query:
            expr: ${"log(" + string(multiplyResult.body.multiplied) + ")"}
    result: logResult
- returnResult:
    return: ${logResult}

工作流程現在會將乘法函式的輸出內容,饋入 math.js 中的記錄函式呼叫。

使用者介面會引導您編輯及部署工作流程。部署完成後,按一下 Execute 執行工作流程。您會看到執行作業的詳細資料:

b40c76ee43a1ce65.png

請注意狀態碼 200body,以及記錄函式的輸出內容。

你剛剛將外部服務整合至我們的工作流程,太棒了!

8. 部署 Cloud Run 服務

在最後一部分,我們會透過呼叫私人 Cloud Run 服務來完成工作流程。也就是說,工作流程必須經過驗證,才能呼叫 Cloud Run 服務。

Cloud Run 服務會傳回傳入數字的 math.floor

建立服務程式碼的目錄並前往該目錄:

mkdir ~/floor
cd ~/floor

在目錄中建立含有以下內容的 app.py 檔案:

import json
import logging
import os
import math

from flask import Flask, request

app = Flask(__name__)

@app.route('/', methods=['POST'])
def handle_post():
    content = json.loads(request.data)
    input = float(content['input'])
    return f"{math.floor(input)}", 200

if __name__ != '__main__':
    # Redirect Flask logs to Gunicorn logs
    gunicorn_logger = logging.getLogger('gunicorn.error')
    app.logger.handlers = gunicorn_logger.handlers
    app.logger.setLevel(gunicorn_logger.level)
    app.logger.info('Service started...')
else:
    app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))

Cloud Run 會部署容器,因此您需要 Dockerfile,而且容器需要繫結至 0.0.0.0PORT 環境變數,因此會出現上述程式碼。

收到 HTTP 要求時,這個函式會從 JSON 主體中擷取 input、呼叫 math.floor,然後將結果傳回給呼叫端。

在同一個目錄中建立下列 Dockerfile

# Use an official lightweight Python image.
# https://hub.docker.com/_/python
FROM python:3.7-slim

# Install production dependencies.
RUN pip install Flask gunicorn

# Copy local code to the container image.
WORKDIR /app
COPY . .

# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
CMD exec gunicorn --bind 0.0.0.0:8080 --workers 1 --threads 8 app:app

建構容器:

export SERVICE_NAME=floor
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}

建構容器後,請將其部署至 Cloud Run。請注意 no-allow-unauthenticated 標記。這樣可確保服務只接受經過驗證的呼叫:

gcloud run deploy ${SERVICE_NAME} \
  --image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
  --platform managed \
  --no-allow-unauthenticated

部署完成後,服務就會準備好執行工作流程。

9. 連結 Cloud Run 服務

如要設定工作流程以呼叫私人 Cloud Run 服務,您必須先建立工作流程可使用的服務帳戶:

export SERVICE_ACCOUNT=workflows-sa
gcloud iam service-accounts create ${SERVICE_ACCOUNT}

run.invoker 角色授予服務帳戶。這樣服務帳戶就能呼叫已驗證的 Cloud Run 服務:

gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
    --member "serviceAccount:${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
    --role "roles/run.invoker"

更新 workflow.yaml 中的工作流程定義,納入 Cloud Run 服務。請注意,您也要加入 auth 欄位,確保 Workflows 在對 Cloud Run 服務的呼叫中傳遞驗證權杖:

- randomgenFunction:
    call: http.get
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/randomgen
    result: randomgenResult
- multiplyFunction:
    call: http.post
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/multiply
        body:
            input: ${randomgenResult.body.random}
    result: multiplyResult
- logFunction:
    call: http.get
    args:
        url: https://api.mathjs.org/v4/
        query:
            expr: ${"log(" + string(multiplyResult.body.multiplied) + ")"}
    result: logResult
- floorFunction:
    call: http.post
    args:
        url: https://floor-<random-hash>.run.app
        auth:
            type: OIDC
        body:
            input: ${logResult.body}
    result: floorResult
- returnResult:
    return: ${floorResult}

更新工作流程。這次傳入服務帳戶:

gcloud workflows deploy workflow \
    --source=workflow.yaml \
    --service-account=${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

執行工作流程:

gcloud workflows execute workflow

幾秒後,您就可以查看工作流程執行結果:

gcloud workflows executions describe <your-execution-id> --workflow workflow

輸出內容會包含整數 resultstate

result: '{"body":"5","code":200 ... } 

...
state: SUCCEEDED

10. 恭喜!

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

涵蓋內容

  • 工作流程的基本概念。
  • 如何將公開 Cloud Functions 連結至工作流程。
  • 如何將私人 Cloud Run 服務連結至工作流程。
  • 如何將外部 HTTP API 連結至 Workflow。