運算服務選擇(VM vs Container vs Serverless)
是什麼?
雲端提供三種主要的運算模式。VM 給你最大控制權、Container 在控制和效率間取得平衡、Serverless 讓你完全不管基礎設施。選擇取決於應用特性、團隊能力和成本考量。
ℹ️趨勢觀察
業界趨勢是從 VM 逐漸遷移到 Container(Kubernetes),再對適合的工作負載採用 Serverless。但 VM 不會消失 — 需要特殊 OS 設定或長時間運行的密集計算仍然用 VM 最合適。
核心觀念
- VM(Virtual Machine):完整的虛擬電腦,有自己的 OS。啟動需要分鐘,可以安裝任何軟體。適合需要完全控制 OS 的場景
- Container(容器):共享 Host OS Kernel,隔離應用程式和依賴。啟動只需秒,通常搭配 Kubernetes 編排。適合微服務架構
- Serverless(函式即服務):只寫函式,雲端自動管理執行環境。按呼叫次數和執行時間計費。適合事件驅動的輕量工作
- Cold Start(冷啟動):Serverless 函式閒置一段時間後,下次觸發需要額外時間啟動執行環境。延遲可能從數百毫秒到數秒
- Container Orchestration(容器編排):Kubernetes(K8s)管理大量 Container 的部署、擴縮、負載均衡、自我修復
常見誤區
⚠️常見誤區
- Serverless 永遠最便宜:低流量時 Serverless 最便宜,但高持續流量下反而比 Container 貴(因為按呼叫計費)
- Container 一定要用 Kubernetes:小型應用用 Azure Container Apps、AWS ECS、Google Cloud Run 就夠了,不需要管理完整的 K8s 集群
- VM 已經過時:需要 GPU 計算、特殊驅動程式、Windows Desktop 應用、或長時間運行的排程任務,VM 仍是最佳選擇
流程/步驟
評估工作負載
長時間運行?事件驅動?需要特殊 OS?
評估團隊能力
有 K8s 經驗嗎?願意學習 Serverless 限制嗎?
估算流量模式
穩定流量?突發流量?間歇性觸發?
計算成本
用雲端計價器比較三種模式的月費
選擇並設計
可以混用 — 核心 API 用 Container,背景任務用 Serverless
流程解讀:選擇運算服務不是非黑即白。先評估工作負載特性(長運行 vs 事件驅動),再考慮團隊能力和流量模式。成本計算是決定性因素之一。實務中常見混用策略 — 核心服務用 Container,事件處理用 Serverless。
程式碼範例
C# 版本
// Azure Functions(Serverless)— 事件驅動
public class OrderFunctions
{
// HTTP 觸發
[Function("ProcessOrder")]
public async Task<IActionResult> ProcessOrder(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
{
var order = await req.ReadFromJsonAsync<OrderDto>();
await _orderService.ProcessAsync(order!);
return new OkObjectResult(new { status = "processed" });
}
// Queue 觸發 — 有新訊息就自動執行
[Function("SendOrderEmail")]
public async Task SendOrderEmail(
[QueueTrigger("order-emails")] OrderEmailMessage message)
{
await _emailService.SendAsync(message.Email, message.OrderId);
}
// Timer 觸發 — 排程執行
[Function("DailyReport")]
public async Task DailyReport(
[TimerTrigger("0 0 8 * * *")] TimerInfo timer) // 每天早上 8 點
{
await _reportService.GenerateDailyAsync();
}
}TypeScript 版本
// AWS Lambda(Serverless)— 事件驅動
import { APIGatewayProxyHandler, SQSHandler } from "aws-lambda";
// HTTP 觸發
export const processOrder: APIGatewayProxyHandler = async (event) => {
const order = JSON.parse(event.body || "{}");
await orderService.process(order);
return {
statusCode: 200,
body: JSON.stringify({ status: "processed" }),
};
};
// SQS 觸發 — Queue 有新訊息就執行
export const sendEmail: SQSHandler = async (event) => {
for (const record of event.Records) {
const message = JSON.parse(record.body);
await emailService.send(message.email, message.orderId);
}
};
// Kubernetes Deployment(Container)— 長時間運行的 API
// deployment.yaml 搭配 TypeScript Express 應用
// 適合持續運行的核心 API 服務Python 版本
# Azure Functions(Python)
import azure.functions as func
app = func.FunctionApp()
# HTTP 觸發
@app.function_name("ProcessOrder")
@app.route(route="orders", methods=["POST"])
async def process_order(req: func.HttpRequest) -> func.HttpResponse:
order = req.get_json()
await order_service.process(order)
return func.HttpResponse('{"status": "processed"}', status_code=200)
# Blob 觸發 — 有新檔案上傳就執行
@app.function_name("ProcessUpload")
@app.blob_trigger(arg_name="blob", path="uploads/{name}", connection="StorageConn")
async def process_upload(blob: func.InputStream):
content = blob.read()
await file_service.process(blob.name, content)
# Google Cloud Run(Managed Container)
# 不需要管 K8s,直接部署 Docker Image
# gcloud run deploy myapi --image gcr.io/myproject/myapi:v1架構圖/概念圖
混合架構中,Load Balancer 將流量分配到不同的運算服務。VM 跑遺留系統、Container 跑核心 API、Serverless 處理非同步事件。三者共存,各司其職。
實戰補充
Q: 怎麼決定該用哪種?
A: 決策樹 — (1) 需要特殊 OS / GPU → VM。(2) 長時間運行的 API / 微服務 → Container。(3) 事件驅動(Queue、Timer、Webhook)→ Serverless。(4) 不確定 → 從 PaaS Container(Cloud Run / Container Apps)開始。
Q: Serverless 的 Cold Start 怎麼解決?
A: (1) 保持函式體積小(減少依賴)。(2) 用 Provisioned Concurrency(預熱實例,但會增加成本)。(3) 定時 Ping 保持 Warm。(4) 對延遲敏感的 API 不適合用 Serverless。
Q: Kubernetes 的學習曲線值得嗎?
A: K8s 的學習曲線陡峭。10 個以下的微服務用 Managed Container 服務(Cloud Run、Container Apps)就夠了。超過 10 個微服務、需要細緻的網路策略和服務治理時,K8s 的投資才值得。
理解測驗
🤔 以下哪種場景最適合 Serverless?
🤔 Serverless 在高持續流量下可能比 Container 貴,為什麼?
🤔 Container 和 VM 最關鍵的架構差異是什麼?
重點整理
💡一句話記住
VM 全控制、Container 好平衡、Serverless 零維運。 口訣:「長跑用 Container、觸發用 Serverless、特殊用 VM」
| 模式 | 啟動時間 | 計費方式 | 適合場景 | |------|---------|---------|---------| | VM | 分鐘 | 按時計費(即使閒置) | 特殊 OS、GPU | | Container | 秒 | 按實例計費 | 微服務、核心 API | | Serverless | 毫秒~秒 | 按呼叫次數+執行時間 | 事件驅動、間歇任務 |