程式碼研究室簡介
1. 簡介
總覽
Cloud Run 函式是 Google Cloud 的函式即服務 (FaaS) 產品,由 Cloud Run 和 Eventarc 提供技術支援,可讓您進一步控管效能和擴充性,並進一步控管函式執行階段和來自 90 多個事件來源的觸發事件。
本程式碼研究室將逐步說明如何建立 Cloud Run 函式,以便回應 HTTP 呼叫,並由 Pub/Sub 訊息和 Cloud Audit Logs 觸發。
本程式碼研究室也使用自動更新基本映像檔功能,藉此為函式部署作業指定基本映像檔,--base-image
自動更新 Cloud Run 的基本映像檔,可讓 Google 自動為基本映像檔的作業系統和語言執行階段元件提供安全性修補程式。您不必重新建構或重新部署服務,即可更新基礎映像檔。詳情請參閱自動更新基本映像檔
如果您不想使用自動基礎映像檔更新功能,可以從本程式碼研究室的範例中移除 --base-image
標記。
課程內容
- 概略說明 Cloud Run 函式,以及如何使用自動基礎映像檔更新功能。
- 如何編寫可回應 HTTP 呼叫的函式。
- 如何編寫回應 Pub/Sub 訊息的函式。
- 如何編寫可回應 Cloud Storage 事件的函式。
- 如何在兩個修訂版本之間拆分流量。
- 如何透過最少的執行個體消除冷啟動。
2. 設定和需求
建立根資料夾
為所有範例建立根目錄。
mkdir crf-codelab cd crf-codelab
設定環境變數
設定在本程式碼研究室中會用到的環境變數。
gcloud config set project <YOUR-PROJECT-ID> REGION=<YOUR_REGION> PROJECT_ID=$(gcloud config get-value project)
啟用 API
啟用所有必要服務:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ logging.googleapis.com \ pubsub.googleapis.com
3. HTTP 函式
針對第一個函式,我們將建立一個已驗證的 Node.js 函式,用於回應 HTTP 要求。我們也將使用 10 分鐘的逾時時間,說明函式如何有更多時間回應 HTTP 要求。
建立
建立應用程式資料夾並前往該資料夾:
mkdir hello-http cd hello-http
建立可回應 HTTP 要求的 index.js
檔案:
const functions = require('@google-cloud/functions-framework'); functions.http('helloWorld', (req, res) => { res.status(200).send('HTTP with Node.js in Cloud Run functions!'); });
建立 package.json
檔案來指定依附元件:
{ "name": "nodejs-run-functions-codelab", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
部署
部署函式:
gcloud run deploy nodejs-run-function \ --source . \ --function helloWorld \ --base-image nodejs22 \ --region $REGION \ --timeout 600 \ --no-allow-unauthenticated
這個指令會使用 Buildpacks,將函式原始碼轉換為可立即用於實際工作環境的容器映像檔。
請注意下列事項:
--source
標記可用來告知 Cloud Run 將函式建構為可執行的容器型服務--function
標記 (新) 用於將新服務的進入點設為要叫用的函式簽章--base-image
旗標 (新功能) 可指定函式的基礎映像檔環境,例如nodejs22
、python312
、go123
、java21
、dotnet8
、ruby33
或php83
。如要進一步瞭解基礎映像檔和各個映像檔中包含的套件,請參閱「執行階段基礎映像檔」。- (選用)
--timeout
標記可讓函式有較長的逾時時間,以便回應 HTTP 要求。在本範例中,600 秒代表 10 分鐘的回應時間。 - (選用)
--no-allow-unauthenticated
,可防止函式公開叫用
測試
使用下列指令測試函式:
# get the Service URL SERVICE_URL="$(gcloud run services describe nodejs-run-function --region $REGION --format 'value(status.url)')" # invoke the service curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
您應該會看到訊息 HTTP with Node.js in Cloud Run functions!
做為回應。
4. Pub/Sub 函式
針對第二個函式,我們將建立 Python 函式,由發布至特定主題的 Pub/Sub 訊息觸發。
設定 Pub/Sub 驗證權杖
如果您是在 2021 年 4 月 8 日當天或之前啟用 Pub/Sub 服務帳戶,請將 iam.serviceAccountTokenCreator
角色授予 Pub/Sub 服務帳戶:
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)') gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \ --role roles/iam.serviceAccountTokenCreator
建立
建立要用於範例的 Pub/Sub 主題:
TOPIC=cloud-run-functions-pubsub-topic gcloud pubsub topics create $TOPIC
建立應用程式資料夾並前往該資料夾:
mkdir ../hello-pubsub cd ../hello-pubsub
建立 main.py
檔案,記錄含有 CloudEvent ID 的訊息:
import functions_framework @functions_framework.cloud_event def hello_pubsub(cloud_event): print('Pub/Sub with Python in Cloud Run functions! Id: ' + cloud_event['id'])
使用以下內容建立 requirements.txt
檔案,以指定依附元件:
functions-framework==3.*
部署
部署函式:
gcloud run deploy python-pubsub-function \ --source . \ --function hello_pubsub \ --base-image python313 \ --region $REGION \ --no-allow-unauthenticated
擷取用於服務帳戶身分的專案編號。
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)')
建立觸發條件
gcloud eventarc triggers create python-pubsub-function-trigger \ --location=$REGION \ --destination-run-service=python-pubsub-function \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \ --transport-topic=projects/$PROJECT_ID/topics/$TOPIC \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
測試
將訊息傳送至主題,藉此測試函式:
gcloud pubsub topics publish $TOPIC --message="Hello World"
您應該會在記錄中看到收到的 CloudEvent:
gcloud run services logs read python-pubsub-function --region $REGION --limit=10
5. Cloud Storage 函式
接下來,我們將建立 Node.js 函式,回應 Cloud Storage 值區的事件。
設定
如要使用 Cloud Storage 函式,請將 pubsub.publisher
IAM 角色授予 Cloud Storage 服務帳戶:
SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER) gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT \ --role roles/pubsub.publisher
建立
建立應用程式資料夾並前往該資料夾:
mkdir ../hello-storage cd ../hello-storage
建立只回應 Cloud Storage 事件的 index.js
檔案:
const functions = require('@google-cloud/functions-framework'); functions.cloudEvent('helloStorage', (cloudevent) => { console.log('Cloud Storage event with Node.js in Cloud Run functions!'); console.log(cloudevent); });
建立 package.json
檔案來指定依附元件:
{ "name": "nodejs-crf-cloud-storage", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
部署
首先,請建立 Cloud Storage 值區 (或使用現有的值區):
export BUCKET_NAME="gcf-storage-$PROJECT_ID" export BUCKET="gs://gcf-storage-$PROJECT_ID" gsutil mb -l $REGION $BUCKET
部署函式:
gcloud run deploy nodejs-crf-cloud-storage \ --source . \ --base-image nodejs22 \ --function helloStorage \ --region $REGION \ --no-allow-unauthenticated
函式部署完成後,您可以在 Cloud 控制台的 Cloud Run 專區中看到該函式。
接著建立 Eventarc 觸發條件。
BUCKET_REGION=$REGION gcloud eventarc triggers create nodejs-crf-cloud-storage-trigger \ --location=$BUCKET_REGION \ --destination-run-service=nodejs-crf-cloud-storage \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=$BUCKET_NAME" \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
測試
將檔案上傳至值區來測試函式:
echo "Hello World" > random.txt gsutil cp random.txt $BUCKET/random.txt
您應該會在記錄中看到收到的 CloudEvent:
gcloud run services logs read nodejs-crf-cloud-storage --region $REGION --limit=10
6. 流量拆分
Cloud Run 函式支援多個函式修訂版本,可在不同修訂版本之間拆分流量,並將函式復原至先前的版本。
在這個步驟中,您將部署 2 個函式修訂版本,然後將流量以 50/50 的比例拆分給這 2 個版本。
建立
建立應用程式資料夾並前往該資料夾:
mkdir ../traffic-splitting cd ../traffic-splitting
建立 main.py
檔案,其中包含可讀取顏色環境變數的 Python 函式,並以該背景顏色回應 Hello World
:
import os color = os.environ.get('COLOR') def hello_world(request): return f'<body style="background-color:{color}"><h1>Hello World!</h1></body>'
使用以下內容建立 requirements.txt
檔案,以指定依附元件:
functions-framework==3.*
部署
部署第一個修訂版本的函式,背景為橘色:
COLOR=orange gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
此時,如果您在瀏覽器中查看 HTTP 觸發條件 (上述部署指令的 URI 輸出內容) 來測試函式,應該會看到背景為橘色的 Hello World
:
部署背景為黃色的第二個修訂版本:
COLOR=yellow gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
由於這是最新修訂版本,因此如果您測試函式,應該會看到背景為黃色的 Hello World
:
將流量拆分為 50/50
如要將流量分配給橘色和黃色修訂版本,您必須找出 Cloud Run 服務的修訂版本 ID。以下是查看修訂版本 ID 的指令:
gcloud run revisions list --service hello-world-colors \ --region $REGION --format 'value(REVISION)'
畫面會顯示如下的輸出內容:
hello-world-colors-00001-man hello-world-colors-00002-wok
接著,請按照下列方式拆分這兩個修訂版本之間的流量 (請根據修訂版本名稱更新 X-XXX
):
gcloud run services update-traffic hello-world-colors \ --region $REGION \ --to-revisions hello-world-colors-0000X-XXX=50,hello-world-colors-0000X-XXX=50
測試
請前往公開網址測試函式。您應該會一半時間看到橘色修訂版本,另一半時間則是黃色修訂版本:
詳情請參閱「復原、漸進式推出及流量遷移」。
7. 執行個體數量下限
在 Cloud Run 函式中,您可以指定要保持暖機狀態、準備好處理要求的最低函式執行個體數量。這有助於限制冷啟動的次數。
在這個步驟中,您將部署初始化速度較慢的函式。您會觀察到冷啟動問題。接著,您會將執行個體數量下限設為 1,然後部署函式,以便消除冷啟動問題。
建立
建立應用程式資料夾並前往該資料夾:
mkdir ../min-instances cd ../min-instances
建立 main.go
檔案。這個 Go 服務具有 init
函式,可讓系統休眠 10 秒,模擬長時間初始化。它也包含 HelloWorld
函式,可回應 HTTP 呼叫:
package p import ( "fmt" "net/http" "time" ) func init() { time.Sleep(10 * time.Second) } func HelloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Slow HTTP Go in Cloud Run functions!") }
部署
部署函式的第一個修訂版本,其中預設的最小例項值為零:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated
使用以下指令測試函式:
# get the Service URL SERVICE_URL="$(gcloud run services describe go-slow-function --region $REGION --format 'value(status.url)')" # invoke the service curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
您會發現第一次呼叫會延遲 10 秒 (冷啟動),然後才會看到訊息。後續的呼叫應立即傳回。
設定執行個體數量下限
如要避免第一次要求時發生冷啟動,請重新部署函式,並將 --min-instances
標記設為 1,如下所示:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated \ --min-instances 1
測試
再次測試函式:
curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
您應該不會再在第一個要求中看到 10 秒的延遲。在首次呼叫 (經過很長的時間後) 發生冷啟動問題的問題已解決,這要歸功於最小執行個體!
詳情請參閱「使用最低執行個體」一文。
8. 恭喜!
恭喜您完成程式碼研究室!
涵蓋內容
- 概略說明 Cloud Run 函式,以及如何使用自動基礎映像檔更新功能。
- 如何編寫可回應 HTTP 呼叫的函式。
- 如何編寫回應 Pub/Sub 訊息的函式。
- 如何編寫可回應 Cloud Storage 事件的函式。
- 如何在兩個修訂版本之間拆分流量。
- 如何透過最少的執行個體消除冷啟動。