概觀

邊緣函數是功能強大的開發人員工具,可透過 CloudFront 在邊緣新增自訂邏輯。邊緣函數使開發人員能夠在減少延遲的同時豐富 Web 應用程式,並建立完全分散的應用程式。邊緣函數可用於:

  • 實作進階 HTTP 邏輯。CloudFront 為您提供原生規則,例如從 HTTP 重新導向到 HTTPS,根據請求路徑進行路由到不同的來源等。邊緣函數允許您超越 CloudFront 的原生功能,實現進階 HTTP 邏輯,例如標準化快取金鑰、重寫 URL、HTTP CRUD 操作等。
  • 減少應用程式延遲。某些應用程式邏輯可以從來源卸載到邊緣,以利用快取 (例如 A/B 測試) 或更靠近使用者執行 (例如 HTTP 重新導向、URL 縮短、HTML 轉譯)。在微服務或微前端架構,您可以在應用程式的入口點使用邊緣函數來實現通用邏輯 (例如授權及驗證),而不是在每個元件單獨實作。
  • 保護應用程式周邊。邊緣函數可用於強制執行安全控制,例如存取控制及邊緣進階地理封鎖。這可讓您減少來源的受攻擊面,並消除不必要的擴展成本。
  • 請求路由。您可以使用邊緣函數,根據應用程式邏輯來將每個 HTTP 請求路由到特定來源。這對於進階容錯移轉、來源負載平衡、多區域架構、遷移、應用程式路由等情況非常有幫助。
     

CloudFront 的邊緣函數類型

CloudFront 為您提供兩種類型的邊緣函數:CloudFront Functions 及 Lambda@Edge。CloudFront Functions 可提供小於毫秒的啟動時間,並立即擴展以處理每秒數百萬個請求,這使其非常適合輕量化邏輯 (快取標準化、URL 重寫、請求操作、授權等…)。Lambda@Edge 是 AWS Lambda 的延伸功能,以跨區域邊緣快取的分散式方式執行。Lambda@Edge 提供了更強大的運算能力及外部網路呼叫等進階功能,而成本及延遲費用更高。本文件提供了有關兩個執行期之間差異的深入詳細資訊。

邊緣函數可用於操縱正在進行的 HTTP 請求及回應,也可用於終止請求並產生回應,而不是在 CloudFront 向上游流動。邊緣函數可以設定為在 CloudFront 的請求生命週期期間在不同事件執行:

  • 檢視器事件:在檢查 CloudFront 快取之前,針對每個請求執行。它非常適合快取標準化、授權或放置唯一的 Cookie。僅針對檢視器事件允許 CloudFront Functions。
  • 來源事件:在快取錯誤時執行,然後轉到來源處取得檔案。理想的做法是在快取內容之前產生內容或操作回應,並將請求動態路由到不同的來源。

請考慮下列最佳實務:

  • 將邊緣函數與最特定的快取行為相關聯,以避免不必要的函數執行成本。
  • 對於在檢視器事件執行的使用案例,選擇 CloudFront Functions;對於在來源事件執行的使用案例,選擇 Lambda@Edge。
  • 只有當 CloudFront Functions 的功能無法滿足邏輯要求時,才轉而使用檢視器事件的 Lambda@Edge。
  • 對於檢視器事件,您可以使用 Lambda@Edge 或 CloudFront Functions,但不能同時使用兩者 (例如,對於檢視器請求事件使用 Lambda@Edge,對於檢視器回應事件使用 CloudFront Functions)。
  • 在設計應用程式時,瞭解邊緣功能的限制

CloudFront Functions

CloudFront Functions 以 JavaScript 編寫,可以完全在 CloudFront 主控台及 API 構建並測試,並可以登入到 us-east-1 區域的 CloudWatch 日誌。作為開發人員,您需要編寫運算使用率低於 80% 的函數。超過運算使用率配額的執行會受到 CloudFront 限制,該執行可以使用 CloudWatch 指標進行監控。

程式設計模型指南可協助您編寫 CloudFront Functions。以下是一個範例函數,用於將來自德國的使用者重新導向到本地化的德語內容:

function handler(event) {
  var request = event.request;
  var headers = request.headers;
  var host = request.headers.host.value;
  var country = 'DE';
  var newurl = `https://${host}/de/index.html`;

  if (headers['cloudfront-viewer-country']) {
    var countryCode = headers['cloudfront-viewer-country'].value;
    if (countryCode === country) {
      var response = {
        statusCode: 302,
        statusDescription: 'Found',
        headers: { location: { value: newurl } },
      };

      return response;
    }
  }
  return request;
}

CloudFront Functions 還提供透過 CloudFront KeyValueStore 從您的程式碼單獨解耦與儲存持久性資料的功能。KeyValueStore 特別適用於內嵌資料 (例如大批重新導向映射) 超過函數大小配額的情形。它的另一項優勢是,讓您能夠更新持久性資料,而無需修改您的函數。

使用 Amazon CloudFront Functions 在邊緣進行自訂

Lambda@Edge

Lambda@Edge 函數可以用 NodeJs 或 Python 編寫。它們使您可以利用具有可配置記憶體 (高達 10 GB) 的 Lambda 容器的強大功能。由於它基於 AWS Lambda,因此 Lambda@Edge 函數是在 Lambda 主控台編寫,而且僅在 us-east-1 編寫。當完成編寫並部署到 CloudFront 發布後,CloudFront 會在全球範圍內複製到其區域邊緣快取。若要將 Lambda@Edge 函數與 CloudFront 快取行為關聯,您必須先發布新版本,然後將其部署到目標快取行為。每個 Lambda@Edge 函數更新都會觸發新的 CloudFront 部署 (與 CloudFront Functions 不同,只有初始關聯才會觸發 CloudFront 部署)。開發 Lambda@Edge 函數時請考慮以下事項:

  • 瞭解使用 Lambda@Edge 的最佳實務,尤其是管理執行並行性方面。並行測量每個區域邊緣快取區域的並行執行 Lambda 容器數目。在每個區域,Lambd@Edge 並行都有突破速度及絕對限制方面的配額。
  • 瞭解從 Lambda@Edge 函數擷取外部資料的最佳實務
  • Lambda@Edge 日誌會以 us-east-1 前綴的日誌群組名稱傳送至執行之區域的 CloudWatch 日誌。如果您需要將 Lambda@Edge 日誌集中在單一區域,請考慮以下 Lambda@Edge 日誌彙總器解決方案。請注意,每次函數執行都會產生日誌到 CloudWatch Logs (與 CloudFront Functions 不同,CloudFront Functions 僅在函數程式碼中明確寫入時才產生日誌)。您可以透過刪除從其關聯的 IAM 角色向 CloudWatch 傳送日誌的權限來停用 Lambda@Edge 日誌。

程式設計模型指南可協助您編寫 Lambda@Edge 函數。以下是出於監管目的將來自德國使用者的請求路由到位於德國的伺服器的範例函數:

'use strict';

exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;

  if (request.headers['cloudfront-viewer-country']) {
    const countryCode = request.headers['cloudfront-viewer-country'][0].value;
    if (countryCode === 'DE') {
      const domainName = 'origin.example.de';
      request.origin.custom.domainName = domainName;
      request.headers['host'] = [{ key: 'host', value: domainName }];
    }
  }

  return request;
};
如何設定 Lambda@Edge 函數

資源

本頁對您是否有幫助?