前言

在上一篇文章中,我們介紹了 AWS 的基礎架構與 IAM 安全概念。本篇將深入探討後端工程師最常接觸的核心服務——運算服務(Compute Services)

AWS 提供了多種運算服務,從傳統的虛擬機器到無伺服器架構,再到容器編排平台。選擇正確的運算服務,直接影響到應用程式的效能、成本與維護複雜度。

本篇將涵蓋以下重點:

  • EC2 執行個體類型選擇與最佳化
  • Lambda 無伺服器架構的適用場景與限制
  • ECS 與 EKS 的容器化部署策略
  • Fargate 無伺服器容器的實務應用
  • 如何根據需求選擇合適的運算服務

運算服務全景圖

在深入各個服務之前,先來了解 AWS 運算服務的整體架構:

graph TB
    subgraph "AWS 運算服務"
        subgraph "虛擬機器"
            A[EC2]
        end
        
        subgraph "容器服務"
            B[ECS]
            C[EKS]
            D[Fargate]
        end
        
        subgraph "無伺服器"
            E[Lambda]
            F[App Runner]
        end
    end
    
    G[你的應用程式] --> A
    G --> B
    G --> C
    G --> E
    
    B --> D
    C --> D
服務 抽象層級 管理複雜度 適用場景
EC2 最低(虛擬機器) 完全控制、特殊需求
ECS 中(容器編排) Docker 容器部署
EKS 中(Kubernetes) 中高 K8s 生態系統
Fargate 高(無伺服器容器) 無需管理底層
Lambda 最高(函數) 最低 事件驅動、短時任務

EC2:彈性運算雲端

EC2 基本概念

EC2(Elastic Compute Cloud)是 AWS 最基礎的運算服務,提供可調整大小的虛擬機器。作為後端工程師,理解 EC2 是掌握其他服務的基礎。

EC2 核心組件

graph LR
    subgraph "EC2 執行個體"
        A[AMI 映像檔] --> B[Instance 執行個體]
        C[Instance Type] --> B
        D[Security Group] --> B
        E[Key Pair] --> B
        B --> F[EBS Volume]
        B --> G[Network Interface]
    end
  • AMI(Amazon Machine Image):作業系統與預裝軟體的模板
  • Instance Type:決定 CPU、記憶體、網路效能
  • Security Group:虛擬防火牆,控制進出流量
  • Key Pair:SSH 登入用的金鑰對
  • EBS Volume:持久化儲存

執行個體類型深度解析

EC2 執行個體類型的命名遵循特定規則:

1
2
3
4
5
m5.2xlarge
│ │ │
│ │ └── 大小(xlarge, 2xlarge, 4xlarge...)
│ └──── 代數(越新越好,效能/價格比更高)
└────── 系列(用途類型)

主要系列與適用場景

系列 特性 適用場景 範例
M 通用平衡型 Web 伺服器、應用程式伺服器 m6i.xlarge
C 運算優化 高 CPU 需求、批次處理 c6i.2xlarge
R 記憶體優化 資料庫、快取伺服器 r6i.4xlarge
T 可突增效能 開發環境、低流量網站 t3.medium
G/P GPU 運算 機器學習、影像處理 g4dn.xlarge
I 儲存優化 高 IOPS 資料庫 i3.large

T 系列的 CPU Credit 機制

T 系列執行個體使用 CPU Credit 機制,這是成本優化的關鍵:

graph TD
    A[基準效能] --> B{CPU 使用率}
    B -->|低於基準| C[累積 Credit]
    B -->|高於基準| D[消耗 Credit]
    D --> E{Credit 餘額}
    E -->|有餘額| F[維持高效能]
    E -->|無餘額| G[限制為基準效能]

T3 執行個體基準效能

類型 vCPU 基準效能 每小時累積 Credit
t3.micro 2 10% 12
t3.small 2 20% 24
t3.medium 2 20% 24
t3.large 2 30% 36

實務建議

  • 開發環境使用 t3.smallt3.medium
  • 生產環境如果 CPU 使用率穩定 > 30%,考慮換用 M 或 C 系列
  • 使用 CloudWatch 監控 CPUCreditBalance 指標

EC2 購買選項與成本優化

pie title EC2 成本優化策略
    "On-Demand" : 30
    "Reserved Instances" : 40
    "Spot Instances" : 20
    "Savings Plans" : 10

各種購買選項比較

選項 折扣幅度 承諾期 適用場景
On-Demand 無折扣 開發測試、臨時需求
Reserved 最高 72% 1-3 年 穩定的生產負載
Spot 最高 90% 無(可被中斷) 批次處理、CI/CD
Savings Plans 最高 72% 1-3 年 混合運算需求

Spot Instance 實務應用

Spot Instance 可以大幅降低成本,但需要處理中斷情況:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Go 語言:處理 Spot 中斷通知
package main

import (
"context"
"log"
"net/http"
"time"
)

const spotTerminationURL = "http://169.254.169.254/latest/meta-data/spot/instance-action"

func checkSpotTermination(ctx context.Context) {
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()

for {
select {
case <-ctx.Done():
return
case <-ticker.C:
resp, err := http.Get(spotTerminationURL)
if err != nil {
continue
}

if resp.StatusCode == 200 {
log.Println("Spot 中斷通知收到,開始優雅關閉...")
// 執行清理工作:
// 1. 停止接受新請求
// 2. 完成進行中的請求
// 3. 保存狀態到持久化儲存
gracefulShutdown()
}
resp.Body.Close()
}
}
}

Spot 最佳實踐

  • 使用多種執行個體類型,分散中斷風險
  • 應用程式設計為無狀態(Stateless)
  • 使用 Auto Scaling Group 的混合模式
  • 適合:CI/CD workers、資料處理、測試環境

Lambda:無伺服器運算

Lambda 核心概念

AWS Lambda 是事件驅動的無伺服器運算服務。你只需要提供程式碼,AWS 負責所有基礎設施管理。

sequenceDiagram
    participant Event as 事件來源
    participant Lambda as Lambda Service
    participant Function as 你的函數
    participant Resource as AWS 資源
    
    Event->>Lambda: 觸發事件
    Lambda->>Function: 執行函數
    Function->>Resource: 存取資源(S3/DynamoDB等)
    Resource-->>Function: 回傳結果
    Function-->>Lambda: 執行完成
    Lambda-->>Event: 回傳回應

Lambda 特性

特性 說明
執行時間限制 最長 15 分鐘
記憶體配置 128 MB - 10,240 MB
暫存空間 /tmp 目錄,最大 10 GB
並發限制 預設 1,000(可申請提高)
計費單位 毫秒級計費

Lambda 適用場景分析

適合使用 Lambda

  • API 後端(搭配 API Gateway)
  • 事件處理(S3 上傳觸發、DynamoDB Streams)
  • 定時任務(CloudWatch Events/EventBridge)
  • 資料轉換(ETL 流程)
  • Webhook 處理

不適合使用 Lambda

  • 長時間運行的任務(> 15 分鐘)
  • 需要持久連線的服務(WebSocket 伺服器)
  • 高頻率、低延遲要求(冷啟動影響)
  • 需要大量本地儲存的應用

Cold Start 問題與解決方案

Cold Start(冷啟動)是 Lambda 最常被討論的效能問題:

graph LR
    A[請求到達] --> B{執行環境}
    B -->|已存在| C[Warm Start<br/>~1-10ms]
    B -->|需建立| D[Cold Start<br/>~100ms-數秒]
    D --> E[下載程式碼]
    E --> F[初始化執行環境]
    F --> G[執行 Init 程式碼]
    G --> H[執行 Handler]
    C --> H

Cold Start 時間因素

因素 影響程度 優化建議
程式語言 Go/Python 較快,Java/C# 較慢
程式碼大小 減少依賴、使用 Lambda Layer
記憶體配置 增加記憶體可加速初始化
VPC 配置 避免不必要的 VPC,使用 VPC 端點

解決方案

  1. Provisioned Concurrency(預置並發)
1
2
3
4
5
# serverless.yml 範例
functions:
api:
handler: main.handler
provisionedConcurrency: 5 # 保持 5 個 warm 執行環境
  1. 定時 Warm Up
1
2
3
4
5
6
7
8
9
10
11
12
13
// 使用 CloudWatch Events 定時觸發,保持執行環境溫熱
func handler(ctx context.Context, event json.RawMessage) error {
// 檢查是否為 warm-up 請求
var warmUp struct {
WarmUp bool `json:"warmUp"`
}
if json.Unmarshal(event, &warmUp) == nil && warmUp.WarmUp {
return nil // 直接返回,不執行業務邏輯
}

// 正常業務邏輯
return processRequest(event)
}

Lambda 與 Go 語言實務

Go 是 Lambda 的理想選擇:編譯為單一二進位檔、冷啟動快速、記憶體效率高。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package main

import (
"context"
"encoding/json"
"log"

"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
)

// 全域變數:在 Init 階段初始化,跨請求復用
var dbClient *dynamodb.Client

func init() {
// Init 階段:只在冷啟動時執行一次
cfg, err := config.LoadDefaultConfig(context.Background())
if err != nil {
log.Fatal(err)
}
dbClient = dynamodb.NewFromConfig(cfg)
}

type Request struct {
UserID string `json:"userId"`
}

type Response struct {
Message string `json:"message"`
Status int `json:"status"`
}

func handler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
var req Request
if err := json.Unmarshal([]byte(request.Body), &req); err != nil {
return events.APIGatewayProxyResponse{
StatusCode: 400,
Body: `{"error": "Invalid request body"}`,
}, nil
}

// 使用復用的 DB Client
// ... 業務邏輯

return events.APIGatewayProxyResponse{
StatusCode: 200,
Body: `{"message": "Success"}`,
Headers: map[string]string{
"Content-Type": "application/json",
},
}, nil
}

func main() {
lambda.Start(handler)
}

效能優化重點

  • init() 函數用於初始化共享資源(DB 連線、HTTP Client)
  • 全域變數在 warm 執行環境中會被復用
  • 避免在 handler 中重複建立連線

ECS:彈性容器服務

ECS 架構概覽

ECS(Elastic Container Service)是 AWS 原生的容器編排服務。相較於 Kubernetes,ECS 更簡單易用,與 AWS 服務整合度更高。

graph TB
    subgraph "ECS 架構"
        A[ECS Cluster] --> B[Service]
        B --> C[Task Definition]
        C --> D[Container Definition]
        
        B --> E[Task 1]
        B --> F[Task 2]
        B --> G[Task N]
        
        subgraph "運行環境"
            H[EC2 Instances]
            I[Fargate]
        end
        
        E --> H
        F --> I
        G --> H
    end

核心概念

概念 說明 類比
Cluster 容器執行的邏輯群組 Kubernetes Cluster
Service 管理 Task 的長期運行服務 Kubernetes Deployment
Task Definition 容器配置的模板 Kubernetes Pod Spec
Task 運行中的容器實例 Kubernetes Pod
Container Definition 單一容器的配置 Kubernetes Container

Task Definition 詳解

Task Definition 是 ECS 的核心配置,定義了容器如何運行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
"family": "my-api-service",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole",
"containerDefinitions": [
{
"name": "api",
"image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-api:latest",
"essential": true,
"portMappings": [
{
"containerPort": 8080,
"protocol": "tcp"
}
],
"environment": [
{
"name": "ENV",
"value": "production"
}
],
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:db-password"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/my-api-service",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
},
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3,
"startPeriod": 60
}
}
]
}

關鍵配置說明

配置 說明
executionRoleArn ECS Agent 使用,用於拉取映像檔、寫入 Log
taskRoleArn 容器內應用程式使用,存取 AWS 資源
networkMode: awsvpc 每個 Task 有獨立 ENI(建議用於 Fargate)
secrets 從 Secrets Manager 或 Parameter Store 注入
healthCheck 容器健康檢查配置

ECS Service 與負載平衡

graph LR
    A[ALB] --> B[Target Group]
    B --> C[Task 1 - AZ-a]
    B --> D[Task 2 - AZ-b]
    B --> E[Task 3 - AZ-c]
    
    F[ECS Service] -->|管理| C
    F -->|管理| D
    F -->|管理| E
    
    G[Auto Scaling] -->|調整| F

Service 配置重點

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"serviceName": "my-api-service",
"cluster": "production-cluster",
"taskDefinition": "my-api-service:5",
"desiredCount": 3,
"launchType": "FARGATE",
"networkConfiguration": {
"awsvpcConfiguration": {
"subnets": ["subnet-xxx", "subnet-yyy"],
"securityGroups": ["sg-xxx"],
"assignPublicIp": "DISABLED"
}
},
"loadBalancers": [
{
"targetGroupArn": "arn:aws:elasticloadbalancing:...",
"containerName": "api",
"containerPort": 8080
}
],
"deploymentConfiguration": {
"maximumPercent": 200,
"minimumHealthyPercent": 100
}
}

ECS 部署策略

graph TD
    subgraph "Rolling Update"
        A1[v1] --> A2[v1 + v2]
        A2 --> A3[v2]
    end
    
    subgraph "Blue/Green"
        B1[Blue v1] --> B2[Green v2]
        B2 --> B3[切換流量]
    end

Rolling Update(預設):

  • 逐步替換舊版本 Task
  • minimumHealthyPercent: 100 表示先啟動新版本,再停止舊版本
  • 零停機時間,但需要雙倍資源

Blue/Green Deployment(搭配 CodeDeploy):

  • 完全獨立的兩個環境
  • 可快速回滾
  • 適合需要快速切換的場景

Fargate:無伺服器容器

Fargate 概念

Fargate 是 ECS 和 EKS 的無伺服器運算引擎。使用 Fargate,你不需要管理 EC2 執行個體,專注於容器本身。

graph TB
    subgraph "ECS on EC2"
        A[你管理 EC2]
        B[你管理容量規劃]
        C[你管理 OS 更新]
        D[AWS 管理容器編排]
    end
    
    subgraph "ECS on Fargate"
        E[AWS 管理一切基礎設施]
        F[你只關心容器配置]
    end

EC2 vs Fargate 選擇

考量因素 EC2 Launch Type Fargate
管理複雜度 高(需管理 EC2) 低(完全託管)
成本(持續運行) 較低 較高(約 20-30%)
成本(間歇運行) 較高 較低(按秒計費)
啟動速度 快(EC2 已運行) 較慢(需啟動基礎設施)
GPU 支援 支援 不支援
大型執行個體 支援 限制較多
Windows 容器 支援 支援(部分功能)

選擇建議

flowchart TD
    A[需要 GPU?] -->|是| B[使用 EC2]
    A -->|否| C[需要超大規格?]
    C -->|是| B
    C -->|否| D[流量模式?]
    D -->|穩定| E[成本敏感?]
    D -->|間歇| F[使用 Fargate]
    E -->|是| B
    E -->|否| F

Fargate 成本優化

Fargate Spot 可以節省高達 70% 的成本:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"capacityProviderStrategy": [
{
"capacityProvider": "FARGATE",
"weight": 1,
"base": 2
},
{
"capacityProvider": "FARGATE_SPOT",
"weight": 4
}
]
}

這個配置表示:

  • 至少 2 個 Task 使用 FARGATE(確保穩定性)
  • 其餘按 1:4 比例分配,優先使用 FARGATE_SPOT

EKS:Kubernetes 服務

何時選擇 EKS

EKS(Elastic Kubernetes Service)是 AWS 託管的 Kubernetes 服務。選擇 EKS 的理由:

選擇 EKS

  • 團隊已有 Kubernetes 經驗
  • 需要跨雲端或混合雲部署
  • 需要 Kubernetes 生態系統工具(Helm、Istio 等)
  • 複雜的微服務架構

選擇 ECS

  • 團隊是 Kubernetes 新手
  • 純 AWS 環境
  • 追求簡單易用
  • 小到中型應用

EKS 架構概覽

graph TB
    subgraph "EKS Cluster"
        subgraph "Control Plane (AWS 管理)"
            A[API Server]
            B[etcd]
            C[Controller Manager]
        end
        
        subgraph "Data Plane (你管理或使用 Fargate)"
            D[Node Group - EC2]
            E[Fargate Profile]
        end
        
        A --> D
        A --> E
    end
    
    F[kubectl] --> A
    G[Helm] --> A

EKS 節點選項

選項 說明 適用場景
Managed Node Groups AWS 管理 EC2 節點 大多數生產環境
Self-Managed Nodes 完全自行管理 特殊客製需求
Fargate 無伺服器節點 間歇性工作負載

運算服務選擇決策樹

flowchart TD
    A[開始選擇運算服務] --> B{應用類型?}
    
    B -->|事件驅動/短時任務| C{執行時間 < 15分鐘?}
    C -->|是| D[Lambda]
    C -->|否| E{需要容器?}
    
    B -->|長期運行服務| E
    
    E -->|否| F[EC2]
    E -->|是| G{團隊有 K8s 經驗?}
    
    G -->|是| H{需要 K8s 生態?}
    H -->|是| I[EKS]
    H -->|否| J[ECS]
    
    G -->|否| J
    
    J --> K{需要管理 EC2?}
    K -->|否| L[Fargate]
    K -->|是/成本考量| M[EC2 Launch Type]
    
    I --> N{節點管理?}
    N -->|簡單| O[Managed Node Groups]
    N -->|無伺服器| P[Fargate for EKS]

實務選擇案例

案例一:API 後端服務

  • 穩定流量、需要持久連線
  • 推薦:ECS + Fargate 或 EKS + Managed Nodes

案例二:圖片處理服務

  • S3 上傳觸發、處理時間短
  • 推薦:Lambda(搭配 S3 Trigger)

案例三:批次資料處理

  • 每天定時執行、可中斷
  • 推薦:ECS + Fargate Spot 或 EC2 Spot

案例四:機器學習推論

  • 需要 GPU、低延遲
  • 推薦:EC2(G 或 P 系列)或 EKS + GPU Nodes

本章重點回顧

關鍵要點

  1. EC2

    • 最大彈性,完全控制
    • 注意執行個體類型選擇與成本優化
    • Spot Instance 可大幅降低成本
  2. Lambda

    • 事件驅動、按執行時間計費
    • 注意 Cold Start 與執行時間限制
    • 適合短時任務與事件處理
  3. ECS/Fargate

    • 容器編排的最佳選擇(對於 AWS 原生應用)
    • Fargate 降低管理負擔
    • 與 AWS 服務整合度高
  4. EKS

    • Kubernetes 標準、跨雲端可攜
    • 學習曲線較陡
    • 適合有 K8s 經驗的團隊

下一篇預告

在系列的第三篇文章中,我們將深入探討 AWS 儲存與資料庫服務

  • S3 物件儲存與最佳實踐
  • RDS 關聯式資料庫選型與優化
  • DynamoDB NoSQL 設計模式
  • ElastiCache 快取策略

系列文章導覽

  • Part 1:入門與核心概念
  • Part 2:運算服務深度解析(本篇)
  • Part 3:儲存與資料庫服務(S3、RDS、DynamoDB)
  • Part 4:網路架構與安全(VPC、ALB、Security Groups)
  • Part 5:訊息佇列與事件驅動(SQS、SNS、EventBridge)
  • Part 6:DevOps 與 CI/CD(CodePipeline、CDK)
  • Part 7:監控與可觀測性(CloudWatch、X-Ray)
  • Part 8:進階架構設計(高可用、災難復原、成本優化)

參考資源