ACE-212:App Engine 應用開發與部署——GCP 原生 PaaS 完全指南
前言
App Engine 是 GCP 最早的服務(2008 年),也是全世界最早的雲端 PaaS 之一。雖然 2025 年 Google 更推薦用 Cloud Run,但 App Engine 到現在還是 ACE 考試的核心考點。原因是它代表「抽象程度最高」的運算模型,而考試最愛考的,就是你能不能在三劍客之間選對。
這是 ACE 進階系列第 7 課,會帶你把 App Engine 的架構、配置和考試要點一次搞懂。
Standard vs Flexible
App Engine 有兩個環境,兩者差很多:
| 特性 | Standard | Flexible |
|---|---|---|
| 底層 | Google 沙盒(gVisor) | Compute Engine VM |
| 語言 | 指定 runtime(Python、Java、Go、Node.js、PHP、Ruby) | 任何語言(Docker 容器) |
| 縮容至零 | ✅ 可以 | ❌ 最少 1 個實例 |
| 啟動速度 | 毫秒級 | 分鐘級(啟動 VM) |
| 檔案系統 | 唯讀(只有 /tmp 可寫) | 可寫(但重啟會消失) |
| WebSocket | ❌ 不支援 | ✅ 支援(with session affinity) |
| VPC 存取 | 需要 VPC Connector | 原生 VPC |
| SSH 連入 | ❌ | ✅ 可以 SSH |
| 免費層 | ✅ 28 F-hours/天 | ❌ 無免費層 |
怎麼選?
需要 scale-to-zero 省錢? → Standard
需要自訂 Docker 映像或特殊語言? → Flexible
需要 WebSocket? → Flexible(或改用 Cloud Run)
要最快啟動? → Standard
App Engine 結構
一個專案一個 App(不可撤銷)
GCP Project
└── App Engine Application(只能有一個,建立後不可刪除、不可換區域)
├── Service: default(必須存在)
│ ├── Version v1(10% 流量)
│ └── Version v2(90% 流量)
├── Service: api
│ └── Version v1(100% 流量)
└── Service: worker
└── Version v1(100% 流量)
⚠️ 重要:
- 每個 GCP 專案只能有 一個 App Engine Application
- 建立後不能刪除(只能停用),也不能變更區域
defaultservice 不能被刪除
app.yaml 配置
# app.yaml(Standard 環境)
runtime: python312
instance_class: F2
automatic_scaling:
target_cpu_utilization: 0.65
min_instances: 0 # 可以縮容至零
max_instances: 10
min_idle_instances: 1 # 保持 1 個暖機實例
env_variables:
ENVIRONMENT: 'production'
handlers:
- url: /static
static_dir: static/
- url: /.*
script: auto
# app.yaml(Flexible 環境)
runtime: custom
env: flex
resources:
cpu: 2
memory_gb: 4
disk_size_gb: 20
automatic_scaling:
min_num_instances: 1 # Flexible 不能是 0
max_num_instances: 20
Instance Class(Standard 環境)
Automatic Scaling(F-class)
用來接用戶請求、需要自動擴縮的服務:
| Class | 記憶體 | CPU | 適合場景 |
|---|---|---|---|
| F1 | 384 MB | 600 MHz | 輕量 API、免費層用 |
| F2 | 768 MB | 1.2 GHz | 一般 Web 應用 |
| F4 | 1.5 GB | 2.4 GHz | 運算密集型 |
| F4_1G | 3 GB | 2.4 GHz | 記憶體密集型 |
Basic / Manual Scaling(B-class)
用來跑背景任務、排程工作:
| Class | 記憶體 | CPU |
|---|---|---|
| B1 | 384 MB | 600 MHz |
| B2 | 768 MB | 1.2 GHz |
| B4 | 1536 MB | 2.4 GHz |
| B4_1G | 3072 MB | 2.4 GHz |
| B8 | 3072 MB | 4.8 GHz |
三種 Scaling 模式
1. Automatic Scaling(預設,Standard)
automatic_scaling:
target_cpu_utilization: 0.65
target_throughput_utilization: 0.6
min_instances: 0
max_instances: 10
min_idle_instances: 1 # 暖機實例,減少冷啟動
max_idle_instances: 3 # 最多閒置實例
max_concurrent_requests: 80
2. Basic Scaling
實例空閒一段時間後自動關閉:
basic_scaling:
max_instances: 5
idle_timeout: 5m # 閒置 5 分鐘後關閉
3. Manual Scaling
固定實例數,不自動擴縮:
manual_scaling:
instances: 3
版本管理與流量分割
部署新版本
# 部署並自動接收所有流量
gcloud app deploy
# 部署但不切換流量(測試用)
gcloud app deploy --no-promote --version=v2
# 查看所有版本
gcloud app versions list
流量分割(金絲雀發布)
# 50/50 分流(隨機分配)
gcloud app services set-traffic default \
--splits=v1=0.5,v2=0.5
# 90/10 分流(Cookie-based,同一用戶固定看到同版本)
gcloud app services set-traffic default \
--splits=v1=0.9,v2=0.1 \
--split-by=cookie
# 按 IP 分流
gcloud app services set-traffic default \
--splits=v1=0.8,v2=0.2 \
--split-by=ip
流量分割方式:
| 方式 | 說明 | 適合場景 |
|---|---|---|
random | 每次請求隨機分配 | A/B 測試 |
cookie | 同用戶固定版本(GOOGAPPUID cookie) | 功能漸進發布 |
ip | 同 IP 固定版本 | 簡單的金絲雀 |
回滾
# 將所有流量切回 v1
gcloud app services set-traffic default --splits=v1=1.0
# 停止舊版本(不再接收流量且釋放資源)
gcloud app versions stop v2
多服務架構(Services)
dispatch.yaml(路由規則)
# dispatch.yaml
dispatch:
- url: '*/api/*'
service: api
- url: '*/admin/*'
service: admin
- url: '*/*'
service: default
# 部署路由規則
gcloud app deploy dispatch.yaml
為不同服務配置不同 app.yaml
# 部署 default 服務
gcloud app deploy app.yaml
# 部署 api 服務(需在 app.yaml 中指定 service: api)
gcloud app deploy api/app.yaml
# 部署 worker 服務
gcloud app deploy worker/app.yaml
定期任務(Cron Jobs)
cron.yaml
# cron.yaml
cron:
- description: 'Daily cleanup'
url: /tasks/cleanup
schedule: every 24 hours
target: worker
- description: 'Hourly report'
url: /tasks/report
schedule: every 1 hours
- description: 'Weekly summary'
url: /tasks/weekly-summary
schedule: every monday 09:00
timezone: Asia/Taipei
# 部署 cron 配置
gcloud app deploy cron.yaml
# 查看 App Engine 應用資訊(位置、預設網域、服務狀態)
# 註:cron 設定無 describe 指令,請至 Cloud Console(App Engine → Cron 工作)查看
gcloud app describe
App Engine 會在排程時間對指定 URL 發一個 HTTP GET 請求。請求的 header 會帶 X-Appengine-Cron: true,你可以用這個來驗證請求是不是真的從 cron 來的。
2025 年 Google 推薦新專案改用 Cloud Scheduler + Cloud Tasks,但 cron.yaml 仍完全支援。
定價
Standard 免費層(每天)
| 項目 | 免費額度 |
|---|---|
| F-class instance-hours | 28 小時/天 |
| B-class instance-hours | 9 小時/天 |
| 儲存 | 5 GB |
| 對外流量 | 1 GB/天 |
Standard 付費
| Instance Class | 費用/小時 |
|---|---|
| F1 / B1 | $0.05 |
| F2 / B2 | $0.10 |
| F4 / B4 | $0.20 |
| F4_1G / B4_1G | $0.30 |
| B8 | $0.40 |
Flexible
- 無免費層
- Per-second 計費(最少 1 分鐘)
- 費用 = vCPU 費 + 記憶體費 + 磁碟費
- 比 Standard 貴,適合需要完整掌控環境的場景
暖機請求(Warm-up Requests)
Standard 環境支援 warm-up request,讓新實例在接正式流量之前先「暖機」一下:
# app.yaml
inbound_services:
- warmup
# Flask 範例
@app.route("/_ah/warmup")
def warmup():
# 預載快取、建立連線池等初始化動作
initialize_caches()
return "", 200, {}
App Engine 啟動新實例時,會先打一個 GET /_ah/warmup,等你的應用程式初始化完成,才開始接正式請求。
遺留 Runtime 與遷移
遺留 Runtime 截止日期
| Runtime | 狀態 | 截止日 |
|---|---|---|
| Python 2.7 | 已停止新部署 | 2026/01/31 |
| Java 8 | 已停止新部署 | 2026/01/31 |
| Go 1.11 | 已停止新部署 | 2026/01/31 |
| PHP 5.5 | 已停止新部署 | 2026/01/31 |
2026 年 1 月 31 日起,這些 runtime 已經不能部署新版本了。已經跑著的應用還是會繼續運行,但建議盡早遷移到第二代 Runtime(Python 3.12、Java 21、Go 1.22 等)。
遺留內建服務
| 服務 | 狀態 | 替代方案 |
|---|---|---|
| Memcache API | 僅 1st gen | Cloud Memorystore |
| Task Queue API | 已棄用 | Cloud Tasks |
| Blobstore | 已棄用 | Cloud Storage |
| Users API | 已棄用 | Identity Platform / Firebase Auth |
App Engine → Cloud Run 遷移
Google 有提供遷移工具,幫你把 app.yaml 轉成 Dockerfile:
# 將 app.yaml 轉換為 Cloud Run 服務(相容性問題會自動列出)
gcloud beta app migrate-to-run --appyaml=app.yaml --entrypoint=ENTRYPOINT
# 或從既有 App Engine 服務直接遷移
gcloud beta app migrate-to-run --service=SERVICE --version=VERSION --entrypoint=ENTRYPOINT
無伺服器三劍客:最終選型決策
| 場景 | 選擇 | 理由 |
|---|---|---|
| GCS 上傳觸發圖片處理 | Cloud Functions | 事件驅動,單一函式 |
| 部署 REST API 微服務 | Cloud Run | 容器化,彈性語言 |
| 快速部署 Web App(MVP) | App Engine Standard | 最簡單,一個 YAML |
| 需要 WebSocket | Cloud Run 或 App Engine Flexible | Standard 不支援 |
| 需要 scale-to-zero 且非容器 | App Engine Standard | 有免費層 |
| 需要自訂 OS/Docker | Cloud Run | 最佳容器支援 |
| 長時間背景任務(> 60 min) | Cloud Run Jobs | 最長 7 天 |
ACE 考試重點整理
必背知識點
- 一個專案只能有一個 App Engine,建立後不可刪除、不可換區域
- Standard 可 scale-to-zero,Flexible 最少 1 個實例
- Standard 啟動毫秒級,Flexible 啟動分鐘級
- Standard 不支援 WebSocket
- F-class 用於 Automatic Scaling,B-class 用於 Basic/Manual Scaling
- 免費層:28 F-hours/天(夠跑一個小型應用)
- cron.yaml 排程任務,發送 HTTP GET 到指定 URL
- 遺留 runtime 已於 2026/01/31 停止新部署——Python 2.7、Java 8、Go 1.11、PHP 5.5 需遷移至第二代
--no-promote部署但不切流量,適合測試
常見陷阱題
Q:App Engine 部署後發現選錯區域,如何修改? A:無法修改。App Engine 的區域建立後不可更改,只能刪除整個 GCP 專案重建。
Q:需要支援 WebSocket 的即時聊天應用,用 App Engine Standard 還是 Flexible? A:Standard 不支援 WebSocket,應選 Flexible。或者更好的選擇是 Cloud Run。
Q:想讓 App Engine 完全不收費,怎麼做?
A:使用 Standard 環境 + F1 instance class + min_instances: 0,在免費層 28 F-hours/天內使用。Flexible 無法免費(至少 1 實例)。
Q:部署新版本後發現 bug,如何快速回滾?
A:gcloud app services set-traffic default --splits=PREVIOUS_VERSION=1.0。
Q:如何讓不同 URL 路由到不同服務?
A:使用 dispatch.yaml 定義路由規則。
實戰範例:部署 Flask Web App
# main.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def home():
return render_template("index.html")
@app.route("/api/health")
def health():
return {"status": "ok"}
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
# app.yaml
runtime: python312
instance_class: F2
entrypoint: gunicorn -b :$PORT main:app
automatic_scaling:
target_cpu_utilization: 0.65
min_instances: 0
max_instances: 5
env_variables:
FLASK_ENV: 'production'
# requirements.txt
flask>=3.0
gunicorn>=22.0
# 部署
gcloud app deploy
# 開啟瀏覽器
gcloud app browse
# 查看日誌
gcloud app logs tail -s default
總結
App Engine 是 GCP 抽象程度最高的運算平台,幾個核心要點:
- Standard vs Flexible:Standard 可 scale-to-zero、毫秒啟動;Flexible 用 Docker、有 WebSocket
- 一個專案一個 App:不可刪除、不可換區域
- Scaling:Automatic(F-class)、Basic、Manual(B-class)
- 流量分割:
--splits支援 random/cookie/ip 三種方式 - 免費層:Standard 28 F-hours/天
- 定位:快速部署 Web App;容器化優先選 Cloud Run;事件驅動選 Cloud Functions
下一課 GCP-112:Firestore 入門,會帶你認識 GCP 最靈活的 NoSQL 方案,以及 ACE 考試必考的資料庫選型。
運算服務選型系列
| 課程 | 服務 | 適合場景 |
|---|---|---|
| GCP-109 | Cloud Run | 容器化 API/微服務,scale-to-zero |
| GCP-111 | Cloud Functions | 事件驅動單一函式(GCS/Pub/Sub 觸發) |
| 本課 ACE-212 | App Engine | 快速部署 Web App、免費層最多 |
| ACE-206 | GKE | 完整 K8s 控制、大規模微服務 |
| ACE-203 | 綜合比較 | 全部 Serverless 選型決策樹 |