跳至主要內容
ESC
ACE 服務實戰 — 第 7/11 篇

ACE-212:App Engine 應用開發與部署——GCP 原生 PaaS 完全指南

ACE-212

前言

App Engine 是 GCP 最早的服務(2008 年),也是全世界最早的雲端 PaaS 之一。雖然 2025 年 Google 更推薦用 Cloud Run,但 App Engine 到現在還是 ACE 考試的核心考點。原因是它代表「抽象程度最高」的運算模型,而考試最愛考的,就是你能不能在三劍客之間選對。

這是 ACE 進階系列第 7 課,會帶你把 App Engine 的架構、配置和考試要點一次搞懂。


Standard vs Flexible

App Engine 有兩個環境,兩者差很多:

特性StandardFlexible
底層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
  • 建立後不能刪除(只能停用),也不能變更區域
  • default service 不能被刪除

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適合場景
F1384 MB600 MHz輕量 API、免費層用
F2768 MB1.2 GHz一般 Web 應用
F41.5 GB2.4 GHz運算密集型
F4_1G3 GB2.4 GHz記憶體密集型

Basic / Manual Scaling(B-class)

用來跑背景任務、排程工作:

Class記憶體CPU
B1384 MB600 MHz
B2768 MB1.2 GHz
B41536 MB2.4 GHz
B4_1G3072 MB2.4 GHz
B83072 MB4.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-hours28 小時/天
B-class instance-hours9 小時/天
儲存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 genCloud 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
需要 WebSocketCloud RunApp Engine FlexibleStandard 不支援
需要 scale-to-zero 且非容器App Engine Standard有免費層
需要自訂 OS/DockerCloud Run最佳容器支援
長時間背景任務(> 60 min)Cloud Run Jobs最長 7 天

ACE 考試重點整理

必背知識點

  1. 一個專案只能有一個 App Engine,建立後不可刪除、不可換區域
  2. Standard 可 scale-to-zero,Flexible 最少 1 個實例
  3. Standard 啟動毫秒級,Flexible 啟動分鐘級
  4. Standard 不支援 WebSocket
  5. F-class 用於 Automatic Scaling,B-class 用於 Basic/Manual Scaling
  6. 免費層:28 F-hours/天(夠跑一個小型應用)
  7. cron.yaml 排程任務,發送 HTTP GET 到指定 URL
  8. 遺留 runtime 已於 2026/01/31 停止新部署——Python 2.7、Java 8、Go 1.11、PHP 5.5 需遷移至第二代
  9. --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-109Cloud Run容器化 API/微服務,scale-to-zero
GCP-111Cloud Functions事件驅動單一函式(GCS/Pub/Sub 觸發)
本課 ACE-212App Engine快速部署 Web App、免費層最多
ACE-206GKE完整 K8s 控制、大規模微服務
ACE-203綜合比較全部 Serverless 選型決策樹
ACE 服務實戰 — 7/11 完成 查看系列全覽 →

留言討論

徽章解鎖!