Featured image of post 無伺服器架構模式:超越 Lambda 函數Featured image of post 無伺服器架構模式:超越 Lambda 函數

無伺服器架構模式:超越 Lambda 函數

探索先進的無伺服器架構模式,包括事件驅動設計、扇出/扇入、傳奇模式、冷啟動緩解和成本優化策略。

無伺服器運算的發展已經遠遠超出了用 API Gateway 背後的 Lambda 函數取代簡單的 REST API 的範圍。現代無伺服器架構是完全事件驅動的、非同步的,並將單體分解為協調的功能工作流程。主要企業現在在 AWS Lambda、Azure Functions 和 Cloudflare Workers 上執行生產工作負載。本文探討了超越基礎知識的模式。

事件驅動架構基礎

無伺服器的核心是事件驅動模型:事件生產者發出事件,事件路由器傳遞事件,事件消費者做出反應。 AWS 提供多種路由服務 — 用於模式感知事件匯流排的 EventBridge、用於基於佇列解耦的 SQS、用於發布/訂閱訊息傳遞的 SNS 以及用於高吞吐量流的 Kafka。

冪等性至關重要:您的函數必須安全地處理重複事件。始終實作冪等鍵和重複資料刪除邏輯。

interface OrderEvent {
  orderId: string;
  idempotencyKey: string;
  items: Array<{ sku: string; quantity: number }>;
}

async function handleOrder(event: OrderEvent) {
  const processed = await checkIdempotency(event.idempotencyKey);
  if (processed) return { status: "duplicate" };
  await processOrder(event.items);
  await markIdempotent(event.idempotencyKey);
  return { status: "processed" };
}

死信佇列 (DLQ) 擷取失敗事件以供以後分析。如果沒有 DLQ,有毒的訊息可能會阻塞整個管道。


扇出/扇入模式

扇出將工作負載分配給並行工作人員;扇入收集結果。 S3 事件通知可以分發到多個 Lambda 函數進行影像處理 - 一個函數產生縮圖,另一個函數提取元數據,第三個函數運行 OCR。

AWS Step Functions 提供具有 Map 狀態的本機扇出:

{
  "Map": {
    "ItemsPath": "$.files",
    "MaxConcurrency": 10,
    "Iterator": {
      "StartAt": "ProcessFile",
      "States": {
        "ProcessFile": {
          "Type": "Task",
          "Resource": "arn:aws:lambda:process-file",
          "End": true
        }
      }
    },
    "ResultPath": "$.results",
    "End": true
  }
}

對於扇入,DynamoDB 充當結果聚合器。每個平行工作執行緒將其結果寫入由相關 ID 作為鍵控的 DynamoDB 專案。一旦計數與預期總數匹配,最終函數就會查詢所有結果。

圖案使用案例延遲
S3 → SQS → Lambda影像處理管道
步驟函數圖協調平行任務分鐘
DynamoDB 串流 → Lambda即時聚合亞秒

分散式事務的 Saga 模式

無伺服器微服務需要分散式事務協調而無需兩階段提交。 saga 模式透過編排(每個服務發布觸發下一個服務的事件)或編排(中央協調器管理工作流程)來處理此問題。

AWS Step Functions 非常適合作為傳奇編排器。每個步驟都是一個任務狀態,補償事務會在失敗時撤銷工作。考慮一個提供航班、飯店和汽車租賃服務的預訂系統:

const sagaDefinition = {
  Comment: "Travel booking saga",
  StartAt: "BookFlight",
  States: {
    BookFlight: {
      Type: "Task",
      Resource: "arn:aws:lambda:book-flight",
      Catch: [{ ErrorEquals: ["States.ALL"], Next: "CancelFlight" }],
      Next: "BookHotel"
    },
    BookHotel: {
      Type: "Task",
      Resource: "arn:aws:lambda:book-hotel",
      Catch: [{ ErrorEquals: ["States.ALL"], Next: "CancelFlight" }],
      Next: "BookCar"
    },
    BookCar: {
      Type: "Task",
      Resource: "arn:aws:lambda:book-car",
      Catch: [{ ErrorEquals: ["States.ALL"], Next: "CancelHotel" }],
      End: true
    },
    CancelFlight: { Type: "Task", Resource: "arn:aws:lambda:cancel-flight", Next: "Fail" },
    CancelHotel: { Type: "Task", Resource: "arn:aws:lambda:cancel-hotel", Next: "Fail" },
    Fail: { Type: "Fail" }
  }
};

如果租車失敗,傳奇會透過補償 Lambda 回滾飯店和航班預訂。 Saga 狀態應該被持久化(例如,在 DynamoDB 中)以便從部分故障中恢復。


冷啟動緩解

當 Lambda 啟動新的執行環境時,就會發生冷啟動。 Java 和 .NET 執行時期的懲罰最高,而 Node.js 和 Python 的啟動時間為數十毫秒。支援 VPC 的功能會增加 ENI 連線的時間。

運行時冷啟動(中位數)冷啟動(第 99 頁)
Node.js45 毫秒250 毫秒
蟒蛇60 毫秒300 毫秒
Java(SnapStart)150 毫秒500 毫秒
Java(無 SnapStart)3,000 毫秒8,000 毫秒
.NET2,500 毫秒7,000 毫秒

預置並發可以使指定數量的環境保持溫暖,但會產生成本。 SnapStart for Java 會拍攝初始化環境的快照,進而大幅減少啟動時間。 「先優化然後緩解」策略效果最好:最小化部署套件、明智地選擇運行時以及修剪依賴項。

使用 EventBridge 的預熱調度程序可以在可預測的流量模式期間保持函數溫暖:

export async function warmUp() {
  const functions = [
    "order-processor", "payment-handler", "notification-service"
  ];
  for (const fn of functions) {
    await lambda.invoke({
      FunctionName: fn,
      InvocationType: "RequestResponse",
      Payload: JSON.stringify({ warmup: true })
    }).promise();
  }
}

無伺服器中的可觀察性

無伺服器可觀察性具有挑戰性:功能是短暫的,追蹤跨越多個服務,並且日誌量很大。使用 JSON 和相關 ID 進行結構化日誌記錄至關重要。

const logger = {
  info: (msg: string, context?: object) => {
    console.log(JSON.stringify({
      level: "INFO",
      message: msg,
      requestId: context?.awsRequestId,
      timestamp: new Date().toISOString(),
      ...context
    }));
  }
};

AWS X-Ray 提供分散式跟踪,OpenTelemetry 透過 Lambda Telemetry API 提供與攤商無關的自動檢測。 Datadog 和 Lumigo 等第三方工具添加了針對無伺服器客製化的儀表板和警報。

成本優化策略

Lambda 定價基於請求:您按呼叫和計算持續時間付費。 ARM64 (Graviton2) 函數的成本比 x86 低 20%。透過演算法優化減少執行時間,直接降低成本。

對大型負載使用 S3,而不是 Lambda 呼叫負載(限制為 256 KB,並按請求計費)。保留並發性以控制擴展並防止失控函數導致成本飆升。

最有效的成本優化是消除不必要的呼叫。定期審核您的函數觸發器:刪除過時的事件規則,整合類似的處理程序,並使用 S3 批次操作而不是針對每個物件的 Lambda 呼叫來進行大規模資料處理。

無伺服器架構現已在生產環境中成熟。事件驅動設計、傳奇編排、冷啟動處理和可觀察性是必備的。採用無伺服器優先的心態,同時對容器何時仍然是正確的選擇保持務實。