結論先行
如果系統已經有一台持續運行的 ECS,而工作只是每天執行幾次的簡單排程,把它放在同一台主機通常很合理。主機已經付費,額外跑一支 script 的邊際成本接近零。為了「看起來比較雲端原生」搬到 Function Compute 或 AWS Lambda,反而會增加部署、權限、觀測與呼叫費用。
Function as a Service(FaaS)真正有價值的地方,不是它也能跑 cron,而是:
- 事件發生時直接執行,不必持續輪詢。
- 工作量突然增加時自動建立更多執行環境。
- 每項工作可以有獨立的權限、資源與失敗範圍。
- 不需要自己管理執行工作所需的主機。
因此我會用一句話區分:
這是「主機固定要做的事」,還是「事件發生後要獨立處理的事」?
前者通常可以留在 ECS,後者才是 Function Compute 或 Lambda 擅長的範圍。
兩種成本不能只看帳單
在小規模系統裡,成本往往比理論上的擴展能力更重要。應比較的不是單一服務價格,而是總成本:
總成本 = 運算費用 + 維運時間 + 失敗處理 + 容量預留 + 系統複雜度
| 選擇 | 省下什麼 | 額外承擔什麼 |
|---|---|---|
| ECS cron/worker | 共用已付費資源,不增加另一套部署 | 主機維護、排程可靠性、資源互相影響 |
| Function Compute/Lambda | 不養閒置 worker,自動擴展並整合事件 | 呼叫與執行費、冷啟動、雲端整合與觀測成本 |
FaaS 通常按請求與執行資源計費,低頻或突發工作可能很划算;但工作若長時間、穩定地消耗資源,常駐 ECS 或 container 的成本可能更可預測。Alibaba Cloud 也把 Function Compute 定位為按需配置資源的事件驅動運算,而不是所有 workload 的預設答案。Function Compute 官方說明
什麼時候留在 ECS?
我會優先留在 ECS,如果:
- ECS 本來就會全天運行,而且仍有容量。
- 工作頻率和資源用量穩定。
- 排程與主系統共用相同程式、資料與部署週期。
- 工作時間較長,或需要本機檔案、特殊 binary、長連線。
- 團隊已有 job table、lock、retry、log 與告警。
例如每天產生一份小型內部報表,查詢的是同一個應用資料庫,也由同一個團隊維護。此時拆成獨立 function,未必產生足以抵銷複雜度的價值。
不過,排程放在主機也要處理幾件事:部署或重啟時是否會漏跑、多台 ECS 是否重複執行、兩輪工作是否重疊,以及大量運算是否拖慢線上 API。簡單系統可以用 lock、執行紀錄與監控解決,不需要一開始就引入更大的平台。
什麼時候使用 Function Compute 或 Lambda?
比較適合 FaaS 的訊號是:
- OSS/S3 出現檔案、queue 收到訊息或 webhook 到達後立刻處理。
- 平常幾乎沒有流量,特定時間會突然爆發。
- 每項工作無狀態、互相獨立,可以大量平行執行。
- 工作需要與主要 API 隔離資源或權限。
- 團隊不想維護另一組 worker 和主機。
- 失敗適合透過 retry、destination 或 dead-letter queue 處理。
例如,使用者上傳圖片後產生縮圖:
flowchart LR
U[使用者上傳] --> O[OSS / S3]
O --> E[Object-created event]
E --> F[Function]
F --> R[縮圖 / metadata]
這比 ECS 每幾分鐘掃描一次 bucket 更直接。Alibaba Function Compute 支援時間、OSS、訊息與 EventBridge 等 trigger;AWS Lambda 同樣支援 S3、SQS、EventBridge Scheduler 等 push 或 pull event source。Alibaba trigger 概覽、AWS event-driven architecture
隔離本身也有價值,但要值得那筆錢
把工作拆出去,除了擴展,也是在切 failure boundary。
如果一個批次任務可能突然吃滿 CPU、記憶體或 database connection,和線上 API 放在同一台 ECS 會互相影響。獨立 function 可以分開資源、權限、部署與 concurrency limit;但團隊也多了一個需要追蹤的 runtime、log、IAM policy 和成本項目。
所以我的原則不是「能拆就拆」,而是:
當隔離帶來的風險降低,大於新增的系統與雲端成本時才拆。
小流量不代表永遠放在一起。可以先共用 ECS,同時保存執行紀錄、避免重複、限制資源,並設定遷移條件:工作開始影響 API、尖峰排隊時間超標、需要由雲端事件即時觸發,或維運成本已高過一個託管 function。
FaaS 和 microservice 不是同一件事
Microservice 描述的是業務能力與團隊邊界;Function Compute 和 Lambda 描述的是部署與執行模型。
- Microservice 可以跑在 ECS、Kubernetes 或 FaaS。
- Function 也可以只是某個較大服務的一個 event handler。
- 把每個小函式獨立部署,不會自動得到好的 microservices,反而可能形成難以追蹤的 nano-services。
應該先決定業務邊界,再替每個 workload 選擇執行位置,而不是先選 serverless 才回頭切系統。
一張實務決策表
| 情境 | 優先考慮 |
|---|---|
| 已有 ECS、低頻小排程 | ECS cron/systemd timer |
| 穩定且持續運算 | ECS/container worker |
| 檔案、訊息或雲端資源事件 | Function Compute/Lambda |
| 低頻但突發、可大量平行 | Function Compute/Lambda |
| 極低延遲且流量穩定 | 常駐服務 |
| 多步驟、長時間、有補償流程 | Workflow/queue/batch platform |
| 尚未確認未來規模 | 先採最簡單方案,設定遷移門檻 |
FaaS 也不是無限彈性。它仍有 concurrency、timeout、payload 和下游容量限制,冷啟動也可能增加延遲。預熱或 provisioned concurrency 可以改善延遲,但又會帶回常駐成本。Function Compute cold-start 指南、AWS Lambda execution environment
最後的判斷
架構不是服務用得越多越成熟。在需求與流量還小的時候,把排程放在既有 ECS,補齊 lock、紀錄和監控,可能就是最符合成本的答案。等到事件整合、隔離或突發擴展成為真實限制,再把那個 workload 搬到 Function Compute 或 Lambda。
這和需求分析是同一件事:先支付今天必要的成本,替高機率變化留下接縫,等證據出現再升級。好的設計不是預先買下所有未來,而是讓未來真正到來時,系統仍然搬得動。