1. 簡介
您可以使用 Workflows 建立無伺服器工作流程,按照您定義的順序將一系列無伺服器工作連結在一起。您可以結合 Google Cloud API、Cloud Functions 和 Cloud Run 等無伺服器產品和呼叫外部 API 的強大功能,打造彈性的無伺服器應用程式。
Workflows 無需管理基礎架構,可視需求順暢調度資源,包括將資源縮減至零。採用「以量計價,即付即用」的定價模式,因此您只需要為執行時間付費。
在本程式碼研究室中,您將瞭解如何將各種 Google Cloud 服務和外部 HTTP API 連結至 Workflows。具體來說,您會將兩項公開 Cloud Functions 服務 (一個 Private Cloud Run 服務和外部公開 HTTP API) 連結至工作流程。
課程內容
- Workflows 的基本概念。
- 如何將公開的 Cloud Functions 與 Workflows 連結。
- 如何將私人 Cloud Run 服務連結至 Workflows。
- 如何透過 Workflows 連結外部 HTTP API。
2. 設定和需求
自修環境設定
提醒您,專案 ID 是所有 Google Cloud 專案的專屬名稱 (已經有人使用上述名稱,很抱歉對您不符!)。稍後在本程式碼研究室中會稱為 PROJECT_ID
。
- 接下來,您需要在 Cloud 控制台中啟用計費功能,才能使用 Google Cloud 資源。
執行這個程式碼研究室並不會產生任何費用,如果有的話。請務必依照「清除所用資源」一節指示本節將說明如何關閉資源,這樣您就不會產生本教學課程結束後產生的費用。Google Cloud 的新使用者符合 $300 美元免費試用計畫的資格。
啟動 Cloud Shell
雖然 Google Cloud 可以從筆記型電腦遠端操作,但在本程式碼研究室中,您將使用 Google Cloud Shell,這是一種在 Cloud 中執行的指令列環境。
在 GCP 控制台的右上方,按一下「Cloud Shell」圖示:
佈建並連線至環境的作業只需幾分鐘的時間。完成後,您應該會看到類似下方的內容:
這部虛擬機器都裝載了您需要的所有開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。這個研究室中的所有工作都可以透過瀏覽器完成。
3. Workflows 總覽
基本資訊
工作流程是由使用 Workflows YAML 語法描述的一系列步驟組成。這是工作流程的定義。如需 Workflows YAML 語法的詳細說明,請參閱語法參考資料頁面。
工作流程一旦建立完成就會部署,讓工作流程準備好執行。執行作業是指工作流程定義中包含邏輯的單次執行作業。所有工作流程執行作業各自獨立,產品可支援大量的並行執行作業。
啟用服務
在這個程式碼研究室中,您會將 Cloud Functions、Cloud Run 服務與 Workflows 連結。建構服務時,您也會用到 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 處理,且需要將其新增為依附元件。Python 中的依附元件是透過 pip 管理,並以名為 requirements.txt
的中繼資料檔案表示。
在相同目錄中建立含有下列內容的 requirements.txt
檔案:
flask>=1.0.2
使用 HTTP 觸發條件部署函式,並使用下列指令允許未經驗證的要求:
gcloud functions deploy randomgen \ --runtime python37 \ --trigger-http \ --allow-unauthenticated
部署函式後,您可以在主控台的 httpsTrigger.url
屬性下方看到函式的網址,或透過 gcloud functions describe
指令顯示。
您也可以使用以下 curl
指令,造訪函式的網址:
curl $(gcloud functions describe randomgen --format='value(httpsTrigger.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 python37 \ --trigger-http \ --allow-unauthenticated
部署函式後,您也可以使用以下 curl
指令造訪函式的網址:
curl $(gcloud functions describe multiply --format='value(httpsTrigger.url)') \ -X POST \ -H "content-type: application/json" \ -d '{"input": 5}'
這個函式已可用於工作流程。
6. 連結兩個 Cloud Functions
在第一個工作流程中,將兩個函式連結在一起。
建立含有以下內容的 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
輸出結果包含 result
和 state
:
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
:
找到所需工作流程,然後按一下「Definition
」分頁標籤:
編輯工作流程定義,並加入對 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
中的記錄函式呼叫。
UI 會引導您編輯及部署工作流程。部署完成後,點選 Execute
即可執行工作流程。畫面上會顯示執行作業的詳細資料:
請注意狀態碼 200
和含有記錄函式輸出內容的 body
。
您剛剛將外部服務整合至我們的工作流程,真是太棒了!
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.0
和 PORT
環境變數,因此才會使用上方的程式碼。
收到 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 服務
您必須先建立 Workflows 使用的服務帳戶,才能設定 Workflows 來呼叫私人 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
輸出結果包含整數 result
和 state
:
result: '{"body":"5","code":200 ... } ... state: SUCCEEDED
10. 恭喜!
恭喜您完成本程式碼研究室。
涵蓋內容
- Workflows 的基本概念。
- 如何將公開的 Cloud Functions 與 Workflows 連結。
- 如何將私人 Cloud Run 服務連結至 Workflows。
- 如何透過 Workflows 連結外部 HTTP API。