跳至主要內容
ESC
GCP 核心服務 — 第 6/10 篇

GCP-111:Cloud Functions 入門——事件驅動無伺服器函式完全指南

GCP-111

前言

Cloud Functions 是 GCP 最簡潔的運算服務,你只要寫一個函式,剩下交給 GCP。有事件來就執行,沒事件就不花錢。不用管容器、不用管伺服器,連程式的進入點怎麼設定都不用煩惱。

這篇文章是 GCP 入門系列第 11 課,帶你認識 Cloud Functions 的核心概念和實際操作。


什麼是 Cloud Functions?

Cloud Functions 讓你部署單一函式來回應事件:

事件來源(HTTP 請求 / GCS 上傳 / Pub/Sub 訊息)


Cloud Functions 自動啟動實例,執行你的函式


處理完成,自動縮容(沒有請求就不花錢)

2024 年 Google 將 Cloud Functions Gen2 更名為 Cloud Run functions,因為 Gen2 底層就是跑在 Cloud Run 上。但 gcloud 指令和介面仍然沿用 functions 名稱。


Gen1 vs Gen2

Gen2 是目前預設且推薦的版本,Gen1 已進入維護模式。

特性Gen1Gen2(推薦)
底層平台獨立系統Cloud Run
並發處理1 個請求/實例最高 1,000 個請求/實例
HTTP 最大逾時9 分鐘60 分鐘
事件驅動最大逾時9 分鐘9 分鐘
最大記憶體8 GiB16 GiB(GA)
最大 CPU4.8 GHz(約 2 vCPU)4 vCPU(GA)
事件來源有限(GCS、Pub/Sub 等)90+ 事件來源(Eventarc)
VPC 連線VPC ConnectorDirect VPC Egress

並發處理——Gen2 的最大優勢

Gen1 每個實例只能處理一個請求。100 個同時請求 = 啟動 100 個實例。

Gen2 支援並發(預設 80),100 個同時請求只需要 2 個實例:

Gen1:100 並發請求 → 100 個實例(100 次冷啟動)
Gen2:100 並發請求 →   2 個實例(2 次冷啟動)

成本和延遲都大幅降低

觸發器類型

HTTP 觸發器

最直接的一種,函式本身就是一個 HTTPS Endpoint:

# Python 範例
import functions_framework

@functions_framework.http
def hello(request):
    name = request.args.get("name", "World")
    return f"Hello, {name}!"
# 部署
gcloud functions deploy hello \
  --gen2 \
  --runtime=python312 \
  --trigger-http \
  --allow-unauthenticated \
  --region=asia-east1 \
  --entry-point=hello

# 取得 URL
gcloud functions describe hello \
  --region=asia-east1 \
  --format="value(serviceConfig.uri)"

Cloud Storage 觸發器

GCS 有檔案變動時自動執行:

import functions_framework
from cloudevents.http import CloudEvent

@functions_framework.cloud_event
def on_file_upload(cloud_event: CloudEvent):
    data = cloud_event.data
    bucket = data["bucket"]
    name = data["name"]
    print(f"New file: gs://{bucket}/{name}")
gcloud functions deploy on-file-upload \
  --gen2 \
  --runtime=python312 \
  --trigger-event-filters="type=google.cloud.storage.object.v1.finalized" \
  --trigger-event-filters="bucket=my-upload-bucket" \
  --region=asia-east1 \
  --entry-point=on_file_upload

Pub/Sub 觸發器

收到 Pub/Sub 訊息時自動執行:

import base64
import functions_framework
from cloudevents.http import CloudEvent

@functions_framework.cloud_event
def on_message(cloud_event: CloudEvent):
    data = base64.b64decode(cloud_event.data["message"]["data"]).decode()
    print(f"Received message: {data}")
gcloud functions deploy on-message \
  --gen2 \
  --runtime=python312 \
  --trigger-topic=my-topic \
  --region=asia-east1 \
  --entry-point=on_message

Eventarc 觸發器(Gen2 獨有)

Gen2 透過 Eventarc 支援 90+ 種事件來源,包括:

  • Cloud SQL 資料庫變更
  • BigQuery 作業完成
  • Cloud Build 建置狀態變更
  • Firestore 文件變更
  • 第三方服務(GitHub、Stripe 等)

支援的語言

語言版本(2026)
Node.js24
Python3.11、3.12、3.13
Go1.23
Java17、21
.NET最新穩定版
Ruby最新穩定版
PHP最新穩定版

資源配置與冷啟動

資源配置

gcloud functions deploy my-func \
  --gen2 \
  --runtime=nodejs24 \
  --trigger-http \
  --memory=512Mi \         # 記憶體(128Mi ~ 16Gi)
  --cpu=1 \                # vCPU(0.083 ~ 4)
  --min-instances=1 \      # 最小實例(消除冷啟動)
  --max-instances=20 \     # 最大實例(控制成本)
  --concurrency=80 \       # 每實例並發數(Gen2)
  --timeout=60 \           # 逾時(秒)
  --region=asia-east1

消除冷啟動

# 保留暖機實例
gcloud functions deploy my-func \
  --min-instances=1

# 設定 0 就是允許縮容至零(預設)
gcloud functions deploy my-func \
  --min-instances=0

事件交付語義

At-Least-Once(至少一次)

Cloud Functions 的事件觸發是 at-least-once 語義,意思是同一個事件可能觸發你的函式好幾次

解法:設計冪等函式

from google.cloud import firestore

db = firestore.Client()

@functions_framework.cloud_event
def process_order(cloud_event):
    event_id = cloud_event["id"]  # 每個事件有唯一 ID

    # 檢查是否已經處理過
    doc = db.collection("processed_events").document(event_id).get()
    if doc.exists:
        print(f"Already processed: {event_id}")
        return

    # 執行業務邏輯
    do_business_logic(cloud_event.data)

    # 記錄已處理
    db.collection("processed_events").document(event_id).set({
        "processed_at": firestore.SERVER_TIMESTAMP
    })

Secret Manager 整合

方式一:部署時引用(推薦)

# 掛載為環境變數
gcloud functions deploy my-func \
  --set-secrets=DB_PASSWORD=db-password:latest

# 掛載為檔案
gcloud functions deploy my-func \
  --set-secrets=/secrets/api-key=api-key:latest

方式二:程式碼中呼叫

from google.cloud import secretmanager

def get_secret(secret_id):
    client = secretmanager.SecretManagerServiceClient()
    name = f"projects/my-project/secrets/{secret_id}/versions/latest"
    response = client.access_secret_version(name=name)
    return response.payload.data.decode("utf-8")

IAM 需求:函式的 Service Account 需要 roles/secretmanager.secretAccessor


本地開發與測試

Cloud Functions 提供 Functions Framework,可在本地模擬雲端執行環境:

安裝與啟動

# Python
pip install functions-framework
functions-framework --target=hello --debug --port=8080

# Node.js
npm install @google-cloud/functions-framework
npx functions-framework --target=hello --port=8080

測試 HTTP 函式

curl http://localhost:8080?name=Bobo

測試事件驅動函式(CloudEvents)

curl -X POST http://localhost:8080 \
  -H "ce-specversion: 1.0" \
  -H "ce-type: google.cloud.storage.object.v1.finalized" \
  -H "ce-source: //storage.googleapis.com/projects/my-project" \
  -H "ce-id: test-001" \
  -H "Content-Type: application/json" \
  -d '{"bucket": "my-bucket", "name": "test.txt"}'

定價與免費層

免費層(每月)

項目免費額度
呼叫次數200 萬次
運算(記憶體)400,000 GB-秒
運算(CPU)200,000 GHz-秒
對外流量5 GB

超過免費層

項目費用
呼叫$0.40 / 100 萬次
CPU$0.000024 / vCPU-秒
記憶體$0.0000025 / GB-秒

定價和 Cloud Run 幾乎一樣,畢竟 Gen2 底層就是 Cloud Run。


Cloud Functions vs Cloud Run vs App Engine

這是 ACE 考試最高頻的選型題:

特性Cloud FunctionsCloud RunApp Engine
部署單位單一函式容器應用程式
語言7 種 runtime任何(Docker)指定 runtime
觸發方式事件 / HTTPHTTPHTTP
最大逾時60 分鐘(HTTP Gen2)60 分鐘24 小時
並發1000/實例(Gen2)1000/實例依 instance class
最適合事件驅動函式容器化微服務傳統 Web 應用
免費層200 萬次/月200 萬次/月28 F-hours/天

選型公式

收到事件(GCS 上傳、Pub/Sub 訊息)→ 執行一個函式?
  → Cloud Functions ✅

部署一個容器化 API / Web Service?
  → Cloud Run ✅

部署一個傳統 Web App,不想管容器?
  → App Engine ✅

ACE 考試重點整理

必背知識點

  1. Gen2 是預設,底層是 Cloud Run,Gen1 進入維護模式
  2. Gen2 支援並發(最高 1000/實例),Gen1 只能 1 個請求/實例
  3. HTTP 觸發最長 60 分鐘(Gen2),事件觸發最長 9 分鐘
  4. 事件交付是 at-least-once,需要冪等設計
  5. Eventarc 讓 Gen2 支援 90+ 種事件來源
  6. 免費層:每月 200 萬次呼叫
  7. Functions Framework 可本地測試

常見陷阱題

Q:Cloud Functions 能處理長時間運行的 ETL 任務嗎? A:HTTP 觸發最長 60 分鐘,事件觸發最長 9 分鐘。超過這個時間就該改用 Cloud Run Jobs(最長 7 天)。

Q:100 個用戶同時呼叫 Gen1 函式,需要幾個實例? A:100 個。Gen1 每實例只能處理 1 個請求。Gen2 只需要 2 個實例(concurrency=80)。

Q:Cloud Functions 保證事件只處理一次嗎? A:不保證。Cloud Functions 是 at-least-once,需要自己設計冪等邏輯。

Q:GCS 上傳自動觸發處理,用什麼服務? A:Cloud Functions(GCS 觸發器最自然的搭配)。


實戰範例:圖片上傳自動生成縮圖

# main.py
import functions_framework
from cloudevents.http import CloudEvent
from google.cloud import storage
from PIL import Image
import io

storage_client = storage.Client()

@functions_framework.cloud_event
def generate_thumbnail(cloud_event: CloudEvent):
    data = cloud_event.data
    bucket_name = data["bucket"]
    file_name = data["name"]

    # 跳過非圖片和已是縮圖的檔案
    if not file_name.lower().endswith((".jpg", ".jpeg", ".png")):
        return
    if file_name.startswith("thumbnails/"):
        return

    # 下載原圖
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(file_name)
    image_data = blob.download_as_bytes()

    # 生成縮圖
    image = Image.open(io.BytesIO(image_data))
    image.thumbnail((200, 200))

    # 上傳縮圖
    output = io.BytesIO()
    image.save(output, format="JPEG", quality=85)
    output.seek(0)

    thumb_blob = bucket.blob(f"thumbnails/{file_name}")
    thumb_blob.upload_from_file(output, content_type="image/jpeg")
    print(f"Thumbnail created: thumbnails/{file_name}")
# 部署
gcloud functions deploy generate-thumbnail \
  --gen2 \
  --runtime=python312 \
  --trigger-event-filters="type=google.cloud.storage.object.v1.finalized" \
  --trigger-event-filters="bucket=my-image-bucket" \
  --region=asia-east1 \
  --memory=512Mi \
  --entry-point=generate_thumbnail

總結

Cloud Functions 是 GCP 最輕量的運算方式,核心要點:

  • Gen2 為預設:底層是 Cloud Run,支援並發(1000/實例)、60 分鐘逾時
  • 觸發器:HTTP、GCS、Pub/Sub、Eventarc(90+ 事件來源)
  • 事件交付:at-least-once,需要冪等設計
  • 本地測試:Functions Framework 模擬雲端環境
  • 免費層:每月 200 萬次呼叫
  • 選型:事件驅動 → Functions;容器化 → Cloud Run;Web App → App Engine

下一課 ACE-212:App Engine 應用開發與部署,學習 GCP 最早的 PaaS 平台如何在 2026 年定位。

運算服務選型系列

課程服務適合場景
GCP-109Cloud Run容器化 API/微服務,scale-to-zero
本課 GCP-111Cloud Functions事件驅動單一函式(GCS/Pub/Sub 觸發)
ACE-212App Engine快速部署 Web App、免費層最多
ACE-206GKE完整 K8s 控制、大規模微服務
ACE-203綜合比較全部 Serverless 選型決策樹
GCP 核心服務 — 6/10 完成 查看系列全覽 →

留言討論

徽章解鎖!