Cloud Run、Cloud Run functions、App Engine 怎麼選?先看執行方式,不要只背產品名稱
「我要部署一個 API,該用 Cloud Run、Cloud Run functions,還是 App Engine?」
這個問題很常見,但只比較產品名稱,通常會愈看愈亂。因為三者都能接 HTTP、都能自動擴充,也都把伺服器維運藏在平台後面。真正拉開差距的,是你的程式要怎麼被呼叫、要執行多久,以及團隊想控制到哪一層。
先把 2026 年的名稱講清楚:Google 現在把函式產品稱為 Cloud Run functions。你仍會在舊專案、API 與指令中看到 Cloud Functions 1st gen 或 gcloud functions deploy,但新式函式也可以直接從 Cloud Run 部署。它不是一個與 Cloud Run 完全分離的世界,而是以 Functions Framework 撰寫、由平台建置成映像,最後以 Cloud Run 服務執行。
如果只想先拿到答案,可以從這四句開始:
- 要提供完整的 Web、API、gRPC 或 WebSocket 服務,先評估 Cloud Run service。
- 只有一個明確的 HTTP 或 CloudEvents 處理函式,希望少管容器細節,評估 Cloud Run function。
- 程式跑完就結束,不需要長期接收請求,使用 Cloud Run job。
- 已有 App Engine 應用且運作穩定,不必只因為 Cloud Run 較新就立刻搬家;新專案則應優先評估 Cloud Run。
後面最重要的不是記住這四句,而是知道什麼情況會讓答案改變。
先分清楚:你要部署的其實是哪一種工作?
1. 持續接收請求的服務
網站、REST API、GraphQL、gRPC 與 WebSocket 都屬於這一類。程式啟動後會監聽連接埠,持續處理進來的請求。
這是 Cloud Run service 最自然的模型。你可以部署容器映像,也可以直接部署支援的原始碼,讓 Cloud Build 與 buildpacks 幫你完成建置。Cloud Run 會提供 HTTPS 端點、TLS、自動擴縮與 revision 流量管理。
2. 收到事件才執行的函式
例如:
- Cloud Storage 收到檔案後產生縮圖
- Pub/Sub 收到訊息後更新資料
- 接收單一路徑的 webhook
- Firestore 資料變動後觸發後續處理
如果一個部署單位就是一個 handler,而且團隊希望用函式簽章處理 HTTP 或 CloudEvents,Cloud Run functions 會比自己架完整 Web framework 更直接。部署時,平台會使用 buildpacks 與 Cloud Build 建置映像,Artifact Registry 則保存產物;「不用自己寫 Dockerfile」不代表背後沒有建置與映像資源。
3. 做完就停止的批次工作
資料匯入、報表產生、資料庫 migration、批次推論與排程腳本,不需要假裝成 HTTP API。這類工作應先看 Cloud Run jobs,再搭配 Cloud Scheduler 或 Workflows 觸發。
4. 持續拉取訊息的背景程序
Kafka consumer、Pub/Sub pull subscriber 或自建 queue worker,不適合偷偷塞在「請求結束後的背景執行」裡。Cloud Run 現在另有 worker pools,專門處理持續運作、非 HTTP、pull-based 的工作;它的擴縮與計費模型和 service 不同,選用前要另外閱讀限制。
這一步很重要。許多選型問題不是 Cloud Run 和 functions 二選一,而是一開始就把批次工作誤包成 Web 服務。
四種平台模型放在同一張表看
| 面向 | Cloud Run service | Cloud Run function | App Engine Standard | App Engine Flexible |
|---|---|---|---|---|
| 主要契約 | 程式監聽 HTTP 連接埠 | Functions Framework 的 HTTP 或 CloudEvents handler | 原始碼與 app.yaml | Runtime 或自訂容器與 app.yaml |
| 部署內容 | 容器映像,或由原始碼建置 | 函式原始碼,由平台建置 | 支援的 runtime 原始碼 | 原始碼或自訂 runtime |
| 適合的粒度 | 完整服務、多路由 API | 單一職責的事件或 HTTP 處理 | App Engine 應用與服務 | 需要 App Engine 模型但有較多 runtime 自由度 |
| 協定 | HTTPS、WebSocket、HTTP/2、gRPC | HTTP 或 CloudEvents handler | 以 HTTP 應用為主 | 以 HTTP 應用為主 |
| Scale to zero | 自動擴縮時可 | 可 | Standard 自動擴縮可 | 不可,至少保留一個執行個體 |
| 版本單位 | Revision | Cloud Run revision | Version | Version |
| 平台控制程度 | 高,可調整容器、並行、CPU、探針與網路 | 較聚焦,平台處理建置與函式啟動 | 遵循 App Engine sandbox 與設定模型 | 以 VM 為基礎,彈性較高但啟動與成本模型不同 |
| 新專案的起點 | 通常先評估 | 明確是函式時評估 | 有 App Engine 特定需求時再選 | 有明確相容性理由時再選 |
這張表刻意不放「冷啟動 300 毫秒」或固定月費。那類數字會受到語言、映像大小、初始化程式、區域、流量、最低執行個體與計費設定影響,拿一個範圍當產品保證,反而會誤導。
Cloud Run service:想掌握服務邊界時的起點
Cloud Run service 的責任分工很清楚:應用程式要能在容器裡啟動、監聽平台指定的連接埠,平台負責路由、擴縮、TLS 與執行環境。
它適合:
- 一個服務有多個 route 或 middleware
- 已有標準 Web framework,例如 Express、FastAPI、Spring Boot 或 ASP.NET Core
- 需要 gRPC、HTTP/2 或 WebSocket
- 需要安裝系統套件或使用特定 runtime
- 希望同一個映像能在本機、CI 與其他容器環境測試
- 需要逐步導流、revision 回滾、最低與最高執行個體等控制
但容器自由度不代表可以沿用傳統 VM 的假設。Cloud Run 執行個體仍然是可拋棄的:本機可寫檔案系統不保證跨執行個體或重啟保留。永久資料應放在 Cloud Storage、資料庫或合適的網路檔案系統。
一個保守的部署起點
gcloud run deploy orders-api \
--source=. \
--region=asia-east1 \
--no-allow-unauthenticated \
--concurrency=20 \
--max-instances=10
這不是所有服務的標準答案,而是一個刻意保守的起點:先要求驗證、限制單一執行個體並行數與總執行個體數,再以負載測試調整。max-instances 也能保護 Cloud SQL 等下游服務,避免流量突增時一起被連線數壓垮。
Cloud Run 的並行上限可以調高,但「平台允許」不代表「程式承受得住」。如果程式使用不可共享的全域狀態、每個請求都吃滿記憶體,或 runtime 的 worker 數量不足,就應先降低 concurrency,再用壓測找出穩定值。
Cloud Run functions:少一點框架,多一個清楚的 handler
Cloud Run function 適合把一個事件映射到一個小而明確的動作。程式透過 Functions Framework 宣告進入點,平台負責把原始碼建置並部署成 Cloud Run 服務。
例如一個 Node.js HTTP function:
import { http } from '@google-cloud/functions-framework';
http('healthcheck', (req, res) => {
res.status(200).send('ok');
});
package.json 至少要包含 Functions Framework:
{
"type": "module",
"dependencies": {
"@google-cloud/functions-framework": "^3.0.0"
}
}
目前的 Cloud Run 部署方式可以寫成:
gcloud run deploy healthcheck \
--source=. \
--function=healthcheck \
--base-image=nodejs24 \
--region=asia-east1 \
--no-allow-unauthenticated
既有自動化若仍使用 Cloud Functions v2 API 或 gcloud functions deploy --gen2,不需要只為了換指令立即重寫;先確認 IAM、Eventarc、Terraform state 與部署流程,再規劃遷移。
什麼時候不要硬拆成函式?
以下情況通常是 Cloud Run service 比較自然:
- 多個 endpoint 共用 middleware、驗證與交易邏輯
- 需要自訂容器啟動方式或系統套件
- 需要 WebSocket 或 gRPC
- 數十個小函式開始出現重複依賴、權限與部署設定
- 團隊其實已經有成熟的 Web service 開發與測試方式
「程式碼很短」不是選 function 的充分條件。邊界是否清楚、事件是否獨立、部署後能否個別擴縮,才是更有用的判斷。
App Engine:不是消失了,而是新專案需要更明確的理由
App Engine Standard 與 Flexible 都仍有正式文件與支援。對既有系統來說,內建版本、service、app.yaml、流量分配與 App Engine API 可能已深深融入應用,盲目搬遷不一定划算。
但 Google 的 App Engine 遷移文件已明確建議:新 Google Cloud 使用者,優先把 Cloud Run 當成 App Engine 的替代方案評估。原因不是 App Engine 「不能用」,而是 Cloud Run 對容器、語言、協定、資源與第三方整合提供了更一致的選擇。
Standard 與 Flexible 不要混為一談
App Engine Standard 在 sandbox 中執行,支援指定的語言 runtime,適合能遵循平台限制的無狀態 Web 應用。自動擴縮時可以 scale to zero,也有 Standard 專屬的 Free Tier 額度。
App Engine Flexible 則以 Compute Engine VM 執行容器,對語言、系統套件與本機檔案操作限制較少,但至少需要一個執行個體,啟動與計費特性也不同。選 Flexible 前,應先問同一個 workload 為什麼不能放在 Cloud Run。
既有 App Engine 應用要不要搬?
可以用三個問題評估:
- 現況是否有明確痛點,例如 runtime、協定、成本或部署速度?
- 應用是否依賴 App Engine bundled services 或特有的 routing 行為?
- 遷移能否分 service 進行,並用流量切換降低風險?
如果答案只是「Cloud Run 比較新」,那不是足夠的商業理由。若痛點是 runtime 停止支援、需要 gRPC,或團隊想統一容器交付流程,遷移才有可衡量的價值。
真正會改變選擇的六個問題
問題一:請求一定能在期限內完成嗎?
Cloud Run service 的 request timeout 可設定到 60 分鐘,App Engine 不同環境與 scaling mode 也有各自限制。WebSocket 雖然受 Cloud Run 支援,連線仍受 request timeout 影響,客戶端必須能重新連線;它不是永久 TCP 連線。
如果工作可能跑數小時,或呼叫端不應一直等待,應把它改成非同步流程:API 先接受任務,寫入 queue 或資料庫,再由 Cloud Run job、Tasks、Workflows 或其他 worker 執行。不要只把 timeout 調到最大,掩蓋錯誤的互動模型。
問題二:程式能安全地同時處理多個請求嗎?
Cloud Run 允許同一執行個體處理多個並行請求。這會影響:
- 全域變數是否會互相覆寫
- 資料庫連線池大小
- 每個請求的記憶體需求
- runtime 的 thread、worker 或 event loop 設定
- 延遲與執行個體數量之間的取捨
concurrency 設得高,可能用較少執行個體完成同樣流量;設得低,則可能改善單一請求的資源競爭。正確值應由壓測與監控決定,不是直接抄平台上限。
問題三:事件重送時,程式會不會做兩次?
Eventarc、Pub/Sub 與其他事件系統通常不能讓你假設「每個事件只處理一次」。重試、重複送達與順序變化都應納入設計。
事件 handler 至少要考慮:
- 用 event ID 或業務鍵做去重
- 寫入操作是否具備 idempotency
- 失敗重試會不會重複寄信、扣款或建立資源
- poison message 如何隔離與告警
- 事件來源與執行服務是否位於相容的區域
這些可靠性問題,比「functions 的事件整合比較方便」更值得在架構評審中討論。
問題四:沒有請求時,真的不會產生成本嗎?
Scale to zero 只描述執行個體數量,不等於整個系統零成本。你仍可能支付:
- Cloud Build 建置時間與 Artifact Registry 儲存
- Cloud Logging、Monitoring 或 Trace 的超額用量
- 網路出站與跨區流量
- Cloud SQL、Redis、Storage 等下游資源
- 最低執行個體、instance-based billing 或 worker pool 執行時間
Cloud Run service 有 request-based 與 instance-based 兩種計費設定。前者預設只在啟動、關閉與處理請求時對 CPU 和記憶體計費;後者則按執行個體整個生命週期計費,適合需要請求外 CPU 或流量長期穩定的情境。成本應用實際流量、資源、區域與下游服務估算,不要只比較「每百萬次請求多少錢」。
問題五:冷啟動是否真的影響使用者?
冷啟動沒有一個適用所有語言與應用的固定數字。映像大小、依賴、初始化工作、CPU、區域、VPC 與最低執行個體都會改變結果。
比較實際的做法是:
- 先量測 p50、p95、p99 與新執行個體啟動時的延遲。
- 把大型初始化移出 request path,能延遲載入的就延遲載入。
- 控制映像與依賴,不在啟動時下載模型或遠端設定。
- 若延遲目標值得固定成本,再設定 minimum instances。
沒有量測就宣稱某產品「毫秒級」、某產品「一定數秒」,對選型幫助不大。
問題六:團隊要維護的是函式,還是服務?
函式的入門程式碼少,但部署數量增加後,IAM、事件、依賴、版本與觀測仍要管理。容器服務多了一層設定,卻可能更符合既有的測試、CI/CD 與本機開發習慣。
最小程式碼量不等於最低總維護成本。選擇應配合團隊能長期除錯與交付的單位。
五個實際場景怎麼判斷
場景一:圖片上傳後產生縮圖
需求是單一 Cloud Storage 事件、處理時間短,而且每次操作可以用物件 generation 或 event ID 去重。優先選 Cloud Run function,透過 Eventarc 觸發。
如果要用大量原生函式庫、GPU,或同一服務包含掃毒、轉檔與多條路由,Cloud Run service 或 job 可能更容易測試與控制。
場景二:有登入、訂單、付款與後台路由的 API
這是一個完整 Web service,不是幾個互不相關的 handler。Cloud Run service 通常較合適,並應一起設計資料庫連線池、maximum instances、IAM 與 revision rollout。
場景三:每天凌晨匯入一批資料
工作有明確開始與結束,不需要常駐 HTTP 端點。使用 Cloud Run job,交給 Cloud Scheduler 或 Workflows 觸發;失敗重試與 checkpoint 應由 job 設計處理。
場景四:既有 App Engine Standard 應用穩定運作
先留在原處,盤點 runtime 支援、bundled services、成本與部署痛點。若要遷移,可以先挑耦合低的 service 搬到 Cloud Run,驗證流量、權限與觀測後再逐步切換。
場景五:即時聊天室或雙向串流
Cloud Run service 支援 WebSocket、HTTP/2 與 gRPC,比 function handler 或 App Engine Standard 自然。不過仍要處理 timeout 後重連、跨執行個體狀態、session affinity 限制與外部狀態儲存。
一張不靠關鍵字猜答案的決策表
| 如果需求是…… | 先評估 | 再確認 |
|---|---|---|
| 完整 Web/API 服務 | Cloud Run service | 協定、concurrency、資料庫連線、驗證 |
| 單一 HTTP 或 CloudEvents handler | Cloud Run function | 重試、去重、runtime、建置產物 |
| 做完即停止的腳本 | Cloud Run job | timeout、重試、task 數、排程方式 |
| 持續 pull queue 的程序 | Cloud Run worker pool 或其他 worker 平台 | 是否需要自建 autoscaler、最低執行個體與成本 |
| 既有 App Engine 系統 | 先維持,再評估 Cloud Run | 相依服務、遷移價值、分階段切流量 |
| 新的 App Engine 候選工作負載 | 優先比較 Cloud Run | 是否真的依賴 App Engine 特定能力 |
上線前的共同檢查清單
不管最後選哪一個產品,至少確認以下項目:
- 服務預設是私人還是公開?誰擁有 invoker 權限?
- 執行 service account 是否只拿到必要權限?
- 區域是否靠近資料,並避免不必要的跨區流量?
- maximum instances 是否會壓垮 Cloud SQL 或第三方 API?
- timeout、retry 與 idempotency 是否一起設計?
- 暫存檔與全域記憶體是否被誤當成持久狀態?
- 是否能從 log、metric 與 trace 找到一次請求的完整路徑?
- 建置映像、Artifact Registry、網路與下游服務是否納入成本?
- 部署失敗或新 revision 異常時,如何回滾?
結論
2026 年在 Google Cloud 上做新的無伺服器應用,Cloud Run 通常是合理的評估起點,但這不等於所有程式都該塞進同一種 Cloud Run resource。
先辨認工作是「持續接請求的 service」、「收到事件的 function」、「做完即停止的 job」,還是「持續拉取工作的 worker」,再比較協定、執行時間、並行、狀態與成本。App Engine 則應用既有投資與明確需求判斷,不必神化,也不必宣判過時。
好的選型不是背出產品規格,而是能說清楚:這個執行模型為什麼符合現在的需求,哪個限制最可能先撞到,以及需求改變時要怎麼遷移。
官方文件
- Cloud Run overview
- Deploy a Cloud Run function
- Write Cloud Run functions
- Cloud Run concurrency
- Cloud Run billing settings
- Compare App Engine and Cloud Run
- App Engine Standard and Flexible environments
產品限制、runtime 與價格會調整。實作前請以部署區域的官方文件與 Pricing Calculator 為準;本文最後查核日期為 2026-07-14。