返回首頁AWS Lambda

AWS Lambda + EventBridge 事件驅動架構實戰教學

17 min 分鐘閱讀
#AWS Lambda#EventBridge#事件驅動#Event Source Mapping#SQS#DynamoDB Streams#Kinesis#非同步處理#DLQ#Serverless

AWS Lambda + EventBridge 事件驅動架構實戰教學

引言:為什麼事件驅動是現代架構的趨勢

你的系統是這樣運作的嗎?

服務 A 直接呼叫服務 B,服務 B 再呼叫服務 C。

一個服務掛了,整條鏈都掛了。

這就是傳統「同步呼叫」架構的問題。服務之間耦合太緊,牽一髮動全身。

事件驅動架構(Event-Driven Architecture)完全不同。

服務之間不直接呼叫,而是透過「事件」溝通。發生了什麼事?誰有興趣就去處理。服務之間鬆耦合,可以獨立擴展、獨立部署。

這篇文章會帶你用 Lambda + EventBridge 建立事件驅動系統。

如果你還不熟悉 Lambda 的基本概念,建議先閱讀 AWS Lambda 完整指南

插圖 1:事件驅動架構 vs 傳統架構對比圖

事件驅動架構概念

在開始實作前,先理解核心概念。

什麼是事件驅動

事件驅動架構的核心是「事件」。

事件(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 通知

  1. 前往 S3 bucket 設定
  2. 屬性 → 事件通知
  3. 啟用「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 完整教學

插圖 2:EventBridge 事件路由流程圖

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:

  1. 前往 DynamoDB 表格設定
  2. 匯出和串流 → DynamoDB Streams
  3. 選擇檢視類型(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 讓你指定成功/失敗時的處理目標。

設定方式:

  1. 前往 Lambda 函數設定
  2. 非同步呼叫 → 目的地
  3. 成功時:SQS、SNS、EventBridge、另一個 Lambda
  4. 失敗時: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 有新訊息時告警
  • 失敗率超過閾值時告警
  • 處理延遲過高時告警

插圖 3:事件驅動系統監控儀表板

常見問題 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 部署的應用程式或災難復原場景。


結語:擁抱事件驅動的未來

事件驅動架構不只是技術選擇,更是思維轉變。

從「這個服務要呼叫哪個服務」轉變為「發生了什麼事,誰需要知道」。

這種思維讓系統更有彈性、更易擴展、更好維護。

關鍵要點回顧:

  1. EventBridge 是事件路由的核心
  2. Event Source Mapping 適合串流型資料
  3. 冪等性設計 是穩健系統的基礎
  4. 監控和 DLQ 確保事件不遺失

如果你需要在 CDN 層面處理事件,可以參考 Lambda@Edge 邊緣運算,在全球節點執行輕量邏輯。

下一步建議:

  • 從簡單的定時任務開始體驗
  • 逐步將同步呼叫改為事件驅動
  • 使用 Terraform 管理 EventBridge 規則

事件驅動架構需要專業規劃?

如果你正在:

  • 設計新的事件驅動系統
  • 將既有架構轉換為 Serverless
  • 處理高流量的即時事件

預約架構諮詢,我們會在 24 小時內回覆你。

正確的事件架構能大幅提升系統彈性與可維護性。


參考資料

  1. AWS 官方文件:Amazon EventBridge User Guide
  2. AWS 官方文件:Lambda Event Source Mappings
  3. AWS 官方文件:Lambda Destinations
  4. AWS Blog:Building event-driven architectures on AWS
  5. AWS Well-Architected:Event-driven architecture

需要專業的雲端建議?

無論您正在評估雲平台、優化現有架構,或尋找節費方案,我們都能提供協助

預約免費諮詢

相關文章