AWS Lambda + EventBridge 事件驅動架構實戰教學
AWS Lambda + EventBridge 事件驅動架構實戰教學
引言:為什麼事件驅動是現代架構的趨勢
你的系統是這樣運作的嗎?
服務 A 直接呼叫服務 B,服務 B 再呼叫服務 C。
一個服務掛了,整條鏈都掛了。
這就是傳統「同步呼叫」架構的問題。服務之間耦合太緊,牽一髮動全身。
事件驅動架構(Event-Driven Architecture)完全不同。
服務之間不直接呼叫,而是透過「事件」溝通。發生了什麼事?誰有興趣就去處理。服務之間鬆耦合,可以獨立擴展、獨立部署。
這篇文章會帶你用 Lambda + EventBridge 建立事件驅動系統。
如果你還不熟悉 Lambda 的基本概念,建議先閱讀 AWS Lambda 完整指南。

事件驅動架構概念
在開始實作前,先理解核心概念。
什麼是事件驅動
事件驅動架構的核心是「事件」。
事件(Event) 是一個已經發生的事實。例如:
- 用戶註冊了
- 訂單成立了
- 檔案上傳了
- 時間到了
當事件發生時,有興趣的服務會被通知並處理。
這與傳統的「命令式」呼叫不同:
- 命令式:「嘿,服務 B,幫我處理這筆訂單」
- 事件式:「有一筆訂單成立了」(誰想處理誰來)
與傳統架構的差異
| 特性 | 傳統同步架構 | 事件驅動架構 |
|---|---|---|
| 服務耦合 | 緊耦合(直接呼叫) | 鬆耦合(透過事件) |
| 失敗影響 | 連鎖失敗 | 隔離失敗 |
| 擴展性 | 需同步擴展 | 可獨立擴展 |
| 回應時間 | 同步等待 | 非同步處理 |
| 新增功能 | 需修改呼叫方 | 只需訂閱事件 |
優點與適用場景
優點:
- 高可用性:單一服務故障不影響整體
- 易擴展:各服務獨立擴展
- 靈活性:新增功能只需訂閱事件
- 成本效益:按事件量付費
適用場景:
- 微服務架構的服務間通訊
- 資料處理 pipeline(ETL)
- 非同步任務處理
- 定時排程任務
- 跨系統整合
不適用場景:
- 需要即時回應的同步操作
- 強一致性要求的交易處理
- 簡單的單體應用
AWS EventBridge 介紹
EventBridge 是 AWS 的 Serverless 事件匯流排服務。
它是事件驅動架構的核心元件。
Event Bus 概念
Event Bus 是事件的「集中站」。
所有事件都發送到 Event Bus,再根據規則路由到目標。
AWS 提供三種 Event Bus:
- default:AWS 服務的預設事件(EC2 狀態變更、S3 事件等)
- custom:自訂 Event Bus,用於應用程式事件
- partner:第三方 SaaS 服務的事件
事件規則(Rules)
Rule 定義「什麼事件」要路由到「哪個目標」。
一個 Rule 包含:
- Event Pattern:過濾條件(符合才處理)
- Target:目標服務(Lambda、SQS、SNS 等)
例如:「當 S3 有新檔案上傳時,觸發 Lambda 處理」
事件模式(Patterns)
Event Pattern 用 JSON 格式定義過濾條件。
{
"source": ["aws.s3"],
"detail-type": ["Object Created"],
"detail": {
"bucket": {
"name": ["my-bucket"]
}
}
}
這個 Pattern 只匹配來自 my-bucket 的物件建立事件。
Pattern 支援多種匹配方式:
- 精確匹配:
"status": ["completed"] - 前綴匹配:
"prefix": "order-" - 數值範圍:
"numeric": [">", 100] - 存在檢查:
"exists": true
Lambda 事件觸發方式
Lambda 支援多種事件觸發方式。理解差異很重要。
同步呼叫 vs 非同步呼叫
同步呼叫(Synchronous):
- 呼叫方等待 Lambda 執行完成
- 適合需要即時回應的場景
- 例如:API Gateway 觸發
非同步呼叫(Asynchronous):
- 呼叫方立即返回,不等待執行結果
- Lambda 會自動重試失敗(最多 2 次)
- 適合背景處理、批次任務
- 例如:S3、EventBridge、SNS 觸發
Event Source Mapping 詳解
Event Source Mapping 是一種特殊的觸發方式。
Lambda 服務會主動從資料來源拉取(poll)事件,而不是被動接收。
支援的來源:
- SQS:訊息佇列
- DynamoDB Streams:資料變更事件
- Kinesis Data Streams:串流資料
- Amazon MQ:訊息代理
- Kafka:分散式串流平台
這種方式的特點:
- Lambda 批次處理多筆事件
- 自動管理 polling 和擴展
- 支援並行處理
Batch Size 與 Batch Window 設定
Event Source Mapping 的兩個關鍵參數:
Batch Size:一次處理幾筆事件
- SQS:1-10,000
- DynamoDB/Kinesis:1-10,000
- 預設:10
Batch Window:最多等待幾秒收集事件
- 範圍:0-300 秒
- 預設:0(有事件就立即處理)
選擇建議:
- 低延遲需求:小 Batch Size + Batch Window = 0
- 高吞吐需求:大 Batch Size + 適當 Batch Window
- 成本優化:大 Batch Size(減少呼叫次數)
想了解 Batch Size 對費用的影響,請參考 AWS Lambda 費用計算完整指南。
不確定該用同步還是非同步?預約架構諮詢,讓專家幫你選擇。
實作教學
來看三個常見的使用情境。
情境一:定時排程任務(Cron)
每天凌晨 3 點執行資料備份。
步驟 1:建立 Lambda 函數
import json
from datetime import datetime
def lambda_handler(event, context):
print(f"Backup started at {datetime.now()}")
# 執行備份邏輯
backup_result = perform_backup()
print(f"Backup completed: {backup_result}")
return {
"status": "success",
"timestamp": str(datetime.now())
}
def perform_backup():
# 實際備份邏輯
return "backup_2024_01_15.tar.gz"
步驟 2:建立 EventBridge 排程規則
前往 EventBridge → 規則 → 建立規則:
- 名稱:
daily-backup-rule - 事件匯流排:
default - 規則類型:排程
- 排程表達式:
cron(0 3 * * ? *)(每天 UTC 03:00) - 目標:選擇你的 Lambda 函數
Cron 表達式說明:
cron(分 時 日 月 星期 年)
cron(0 3 * * ? *) = 每天 03:00
cron(0 */2 * * ? *) = 每 2 小時
cron(0 9 ? * MON *) = 每週一 09:00
情境二:S3 → EventBridge → Lambda
檔案上傳到 S3 時自動處理。
步驟 1:啟用 S3 EventBridge 通知
- 前往 S3 bucket 設定
- 屬性 → 事件通知
- 啟用「Amazon EventBridge」
步驟 2:建立 EventBridge 規則
Event Pattern:
{
"source": ["aws.s3"],
"detail-type": ["Object Created"],
"detail": {
"bucket": {
"name": ["my-upload-bucket"]
},
"object": {
"key": [{
"prefix": "uploads/"
}]
}
}
}
步驟 3:Lambda 處理函數
import json
import boto3
s3 = boto3.client('s3')
def lambda_handler(event, context):
# 從 EventBridge 事件取得 S3 資訊
detail = event['detail']
bucket = detail['bucket']['name']
key = detail['object']['key']
print(f"Processing file: s3://{bucket}/{key}")
# 讀取檔案
response = s3.get_object(Bucket=bucket, Key=key)
content = response['Body'].read()
# 處理檔案(例如:轉換格式、分析內容)
result = process_file(content)
return {"status": "processed", "file": key}
情境三:自訂事件(PutEvents)
應用程式發送自訂事件。
發送事件(Python SDK):
import boto3
import json
eventbridge = boto3.client('events')
def send_order_created_event(order):
response = eventbridge.put_events(
Entries=[
{
'Source': 'myapp.orders',
'DetailType': 'Order Created',
'Detail': json.dumps({
'orderId': order['id'],
'customerId': order['customer_id'],
'amount': order['amount'],
'items': order['items']
}),
'EventBusName': 'my-custom-bus'
}
]
)
return response
訂閱事件(EventBridge Rule):
{
"source": ["myapp.orders"],
"detail-type": ["Order Created"],
"detail": {
"amount": [{
"numeric": [">=", 1000]
}]
}
}
這個規則只處理金額 >= 1000 的訂單。
如果你想用 Infrastructure as Code 管理這些設定,請參考 Terraform 部署 AWS Lambda 完整教學。

Event Source Mapping 進階
Event Source Mapping 適合處理串流型資料。
SQS 整合(標準 vs FIFO)
標準佇列:
- 高吞吐量(每秒數十萬訊息)
- 至少一次傳遞(可能重複)
- 適合容忍重複的場景
FIFO 佇列:
- 嚴格順序保證
- 精確一次傳遞
- 適合順序敏感的場景
Lambda 設定:
# SQS 觸發的 Lambda Handler
def lambda_handler(event, context):
for record in event['Records']:
body = json.loads(record['body'])
message_id = record['messageId']
try:
process_message(body)
except Exception as e:
# 處理失敗,訊息會回到佇列重試
print(f"Error processing {message_id}: {e}")
raise
return {"processed": len(event['Records'])}
DynamoDB Streams
監聽 DynamoDB 資料變更事件。
啟用 Streams:
- 前往 DynamoDB 表格設定
- 匯出和串流 → DynamoDB Streams
- 選擇檢視類型(NEW_IMAGE、OLD_IMAGE、BOTH、KEYS_ONLY)
Lambda 處理:
def lambda_handler(event, context):
for record in event['Records']:
event_name = record['eventName'] # INSERT, MODIFY, REMOVE
if event_name == 'INSERT':
new_item = record['dynamodb']['NewImage']
handle_new_item(new_item)
elif event_name == 'MODIFY':
old_item = record['dynamodb']['OldImage']
new_item = record['dynamodb']['NewImage']
handle_update(old_item, new_item)
elif event_name == 'REMOVE':
old_item = record['dynamodb']['OldImage']
handle_delete(old_item)
return {"processed": len(event['Records'])}
Kinesis Data Streams
處理即時串流資料。
特點:
- 高吞吐量(每 shard 每秒 1MB/1000 records)
- 資料保留 24 小時(可延長至 7 天)
- 支援多個消費者
Lambda 設定考量:
- Batch Size:根據處理能力調整
- Parallelization Factor:每個 shard 的並行處理數
- Starting Position:LATEST 或 TRIM_HORIZON
事件驅動架構設計很複雜? SQS、Kinesis、DynamoDB Streams 各有適用場景。
預約架構諮詢,讓我們幫你設計最佳事件流。
非同步處理與錯誤處理
事件驅動系統的錯誤處理與同步系統不同。
Lambda Destinations
Lambda Destinations 讓你指定成功/失敗時的處理目標。
設定方式:
- 前往 Lambda 函數設定
- 非同步呼叫 → 目的地
- 成功時:SQS、SNS、EventBridge、另一個 Lambda
- 失敗時:SQS、SNS、EventBridge、另一個 Lambda
適用場景:
- 成功時通知下游服務
- 失敗時發送告警或存入 DLQ
DLQ(Dead Letter Queue)
處理失敗的事件需要有個去處。
DLQ 會捕捉所有重試失敗的事件,讓你可以:
- 分析失敗原因
- 手動重新處理
- 發送告警通知
設定 DLQ:
# 使用 SAM/CloudFormation
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
DeadLetterQueue:
Type: SQS
TargetArn: !GetAtt DeadLetterQueue.Arn
DeadLetterQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: my-function-dlq
更多錯誤處理細節,請參考 AWS Lambda 錯誤處理完整指南。
重試機制設定
非同步呼叫的預設重試:
- 最多重試 2 次
- 事件保留最長 6 小時
自訂設定:
# 使用 AWS CLI 設定
aws lambda put-function-event-invoke-config \
--function-name my-function \
--maximum-retry-attempts 1 \
--maximum-event-age-in-seconds 3600
Event Source Mapping 的重試:
- 會持續重試直到成功或資料過期
- 可設定 bisectBatchOnFunctionError 分割批次處理
最佳實踐
建立穩健的事件驅動系統需要遵循一些原則。
冪等性設計
事件可能被處理多次(網路重傳、重試機制)。
冪等性:同一個事件處理多次,結果與處理一次相同。
實作方式:
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('processed-events')
def lambda_handler(event, context):
event_id = event['id']
# 檢查是否已處理過
try:
table.put_item(
Item={'eventId': event_id, 'processedAt': datetime.now().isoformat()},
ConditionExpression='attribute_not_exists(eventId)'
)
except dynamodb.meta.client.exceptions.ConditionalCheckFailedException:
print(f"Event {event_id} already processed, skipping")
return {"status": "skipped"}
# 處理事件
result = process_event(event)
return {"status": "processed", "result": result}
事件版本管理
事件格式會隨時間演變。
建議做法:
- 在事件中加入版本號
- 保持向後相容
- 使用 Schema Registry 管理事件結構
{
"version": "1.0",
"source": "myapp.orders",
"detail-type": "Order Created",
"detail": {
"orderId": "12345",
"version": "v2",
"data": { ... }
}
}
監控與追蹤
關鍵指標:
- 事件處理延遲
- 失敗率
- DLQ 訊息數量
- 並發執行數
設定 CloudWatch Alarms:
- DLQ 有新訊息時告警
- 失敗率超過閾值時告警
- 處理延遲過高時告警

常見問題 FAQ
EventBridge 和 SNS/SQS 有什麼差別?
EventBridge 專注於事件路由和過濾,支援複雜的事件模式匹配;SNS 是發布/訂閱服務,適合簡單的訊息廣播;SQS 是訊息佇列,適合解耦和削峰。三者可以組合使用:EventBridge 路由事件到 SNS 廣播,或到 SQS 緩衝處理。
Event Source Mapping 的 Batch Size 怎麼選?
根據單筆事件處理時間和整體延遲需求決定。如果單筆處理 100ms,Batch Size 100 可能導致 10 秒延遲。建議從小值開始(10-50),監控效能後逐步調整。成本敏感時可增加 Batch Size 減少呼叫次數。
如何確保事件不會遺失?
使用 DLQ 捕捉處理失敗的事件,設定適當的重試機制,實作冪等性處理以支援安全重試。對於關鍵事件,考慮將事件先存入持久化儲存(S3、DynamoDB)再處理。
EventBridge 規則可以跨 Region 嗎?
可以。使用 EventBridge 的跨 Region 事件功能,可以將事件路由到其他 Region 的 Event Bus。這適合多 Region 部署的應用程式或災難復原場景。
結語:擁抱事件驅動的未來
事件驅動架構不只是技術選擇,更是思維轉變。
從「這個服務要呼叫哪個服務」轉變為「發生了什麼事,誰需要知道」。
這種思維讓系統更有彈性、更易擴展、更好維護。
關鍵要點回顧:
- EventBridge 是事件路由的核心
- Event Source Mapping 適合串流型資料
- 冪等性設計 是穩健系統的基礎
- 監控和 DLQ 確保事件不遺失
如果你需要在 CDN 層面處理事件,可以參考 Lambda@Edge 邊緣運算,在全球節點執行輕量邏輯。
下一步建議:
- 從簡單的定時任務開始體驗
- 逐步將同步呼叫改為事件驅動
- 使用 Terraform 管理 EventBridge 規則
事件驅動架構需要專業規劃?
如果你正在:
- 設計新的事件驅動系統
- 將既有架構轉換為 Serverless
- 處理高流量的即時事件
預約架構諮詢,我們會在 24 小時內回覆你。
正確的事件架構能大幅提升系統彈性與可維護性。
參考資料
- AWS 官方文件:Amazon EventBridge User Guide
- AWS 官方文件:Lambda Event Source Mappings
- AWS 官方文件:Lambda Destinations
- AWS Blog:Building event-driven architectures on AWS
- AWS Well-Architected:Event-driven architecture
相關文章
AWS Lambda 錯誤處理完整指南:502、503、504 錯誤解決方案
Lambda 出現 502、503、504 錯誤怎麼辦?本文詳解各錯誤原因與解決方案,包含程式碼範例、偵錯技巧,幫你快速排除問題。
AWS LambdaLambda@Edge 完整指南:CDN 邊緣運算應用與實戰
Lambda@Edge 是什麼?本文完整解析 CDN 邊緣運算,包含執行時機點、限制、實戰應用(URL 重寫、A/B 測試、圖片優化),幫你在 CloudFront 上實現進階功能。
AWS LambdaTerraform 部署 AWS Lambda 完整教學:IaC 最佳實踐
如何用 Terraform 部署 AWS Lambda?本文完整教學 IaC 最佳實踐,包含 Module 使用、CI/CD 整合、多環境部署,幫你實現可重複的基礎設施管理。