本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 Lambda 遞迴迴圈偵測來防止無限迴圈
當您將 Lambda 函數設定為輸出至調用該函數的相同服務或資源時,就可以建立無限遞迴迴圈。例如,Lambda 函數可能會將訊息寫入 Amazon Simple Queue Service (Amazon SQS) 佇列,然後調用相同的函數。此調用會導致函數將另一則訊息寫入佇列,進而再次調用函數。
非蓄意遞迴循環可能會導致意外費用向您的 收取 AWS 帳戶。迴圈也可能導致 Lambda 擴展和使用您帳戶的所有可用並行處理。為了協助降低意外迴圈的影響,Lambda 會在發生特定類型的遞迴循環後,立即偵測到這些循環。根據預設,當 Lambda 偵測到遞迴迴圈時,它會停止叫用函數並通知您。如果您的設計刻意使用遞迴模式,您可以變更函數的預設組態,以允許遞迴調用。如需更多資訊,請參閱允許 Lambda 函數在遞迴迴圈中執行。
了解遞迴迴圈偵測
Lambda 中的遞迴迴圈偵測透過追蹤事件來運作。Lambda 是事件驅動型運算服務,可在特定事件發生時執行函數程式碼。例如,當項目新增至 Amazon SQS佇列或 Amazon Simple Notification Service (AmazonSNS) 主題時。Lambda 會將事件作為JSON物件傳遞至您的函數,其中包含系統狀態變更的相關資訊。當事件導致函數執行時,這稱為調用。
若要偵測遞迴迴圈,Lambda 會使用 AWS X-Ray 追蹤標頭。當支援遞迴迴圈偵測的AWS 服務 將事件傳送至 Lambda 時,這些事件會自動使用中繼資料進行註解。當您的 Lambda 函數 AWS 服務 使用支援的 版本 AWS SDK將其中一個事件寫入到另一個支援的事件時,它會更新此中繼資料。更新後的中繼資料包含事件調用函數的次數計數。
注意
您不需要啟用 X-Ray 作用中追蹤,即可使用此功能。依預設,所有 AWS 客戶都會開啟遞迴迴路偵測。使用此功能無需支付任何費用。
請求鏈是由相同觸發事件引起的一系列 Lambda 調用。例如,假設 Amazon SQS佇列調用您的 Lambda 函數。然後,您的 Lambda 函數會將處理的事件傳回相同的 Amazon SQS佇列,這會再次調用您的函數。在此範例中,函數的每次調用都屬於相同的請求鏈。
如果您的函數在相同的請求鏈中被叫用約 16 次,則 Lambda 會自動停止該請求鏈中的下一個函數叫用,並通知您。如果函數設有多個觸發條件,來自其他觸發條件的調用不會受影響。
注意
即使來源佇列的重新驅動政策上的maxReceiveCount
設定高於 16,Lambda 遞迴保護也不會阻止 Amazon 在偵測到遞迴循環並終止之後SQS重試訊息。當 Lambda 偵測到遞迴迴圈並捨棄後續調用時,會將 RecursiveInvocationException
傳回至事件來源映射。這會增加訊息上的receiveCount
值。Lambda 會繼續重試訊息,並繼續封鎖函數叫用,直到 Amazon SQS判斷超過 maxReceiveCount
,並將訊息傳送至設定的無效字母佇列。
如果您為函數設定了故障時的目的地或無效字母佇列,則 Lambda 也會將事件從已停止的調用中傳送至目的地或無效字母佇列。為函數設定目的地或無效字母佇列時,請務必不要使用函數也用作事件觸發或事件來源映射的 Amazon SNS主題或 Amazon SQS佇列。如果將事件傳送到調用函數的相同資源,則可以建立另一個遞迴迴圈。
支援的 AWS 服務 和 SDKs
Lambda 只能偵測包含某些支援 的遞迴迴圈 AWS 服務。若要偵測遞迴循環,您的函數也必須使用其中一個支援的 AWS SDKs。
支援的 AWS 服務
Lambda 目前偵測到函數、Amazon SQS、Amazon S3 和 Amazon 之間的遞迴循環SNS。Lambda 也會偵測僅由 Lambda 函數組成的迴圈,這些函數可以同步或非同步相互調用。下圖顯示 Lambda 可以偵測的一些迴圈範例:
當 Amazon DynamoDB AWS 服務 等其他 構成迴圈的一部分時,Lambda 目前無法偵測並停止它。
由於 Lambda 目前只偵測到涉及 Amazon SQS、Amazon S3 和 Amazon 的遞迴迴圈SNS,因此涉及其他 的迴圈仍可能導致 Lambda 函數 AWS 服務 意外使用。
為了防止向您的 收取意外費用 AWS 帳戶,建議您設定 Amazon CloudWatch 警示,以提醒您不尋常的使用模式。例如,您可以設定 CloudWatch 來通知您 Lambda 函數並行或調用中的峰值。也可以設定帳單警示,當帳戶中的支出超過指定的閾值時通知您。或者,可以使用 AWS Cost Anomaly Detection 來提醒您不尋常的帳單模式。
支援的 AWS SDKs
若要讓 Lambda 偵測遞迴迴圈,您的函數必須使用下列其中一個SDK版本或更高版本:
執行期 | 最低必要 AWS SDK版本 |
---|---|
Node.js |
2.1147.0 (SDK第 2 版) 3.105.0 (SDK第 3 版) |
Python |
1.24.46 (boto3) 1.27.46 (botocore) |
Java 8 和 Java 11 |
2.17.135 |
Java 17 |
2.20.81 |
Java 21 |
2.21.24 |
.NET |
3.7.293.0 |
Ruby |
3.134.0 |
PHP |
3.232.0 |
Go |
SDK V2 (使用最新版本) |
某些 Lambda 執行期,例如 Python 和 Node.js,包括 的版本 AWS SDK。如果函數執行時間中包含的SDK版本低於所需的最低版本,則您可以將支援的 版本新增至SDK函數的部署套件 。您也可以使用 Lambda 層 將支援的SDK版本新增至函數。如需每個 Lambda 執行時間SDKs隨附的 清單,請參閱 Lambda 執行期。
遞迴迴圈通知
當 Lambda 停止遞迴迴圈時,您會透過 AWS Health Dashboard
AWS Health Dashboard 通知
當 Lambda 停止遞迴調用時, 會在您的帳戶運作狀態頁面上,於開啟和最近問題
電子郵件提醒
當 Lambda 第一次停止函數的遞迴調用時,會傳送電子郵件提醒給您。對於 AWS 帳戶中的每個函數,Lambda 每 24 小時最多傳送一封電子郵件。Lambda 傳送電子郵件通知後,即使 Lambda 停止函數的進一步遞迴調用,在接下來的 24 小時也不會再收到該函數的任何電子郵件。請注意,在 Lambda 停止遞迴調用後,可能需要三個小時才會收到此電子郵件提醒。
Lambda 會傳送遞迴循環電子郵件提醒給您 AWS 帳戶的主要帳戶聯絡人和替代操作聯絡人。如需有關檢視或更新帳戶中電子郵件地址的資訊,請參閱《AWS 一般參考》中的更新聯絡資訊。
Amazon CloudWatch 指標
此CloudWatch 指標會RecursiveInvocationsDropped
記錄 Lambda 因為在單一請求鏈中調用函數超過約 16 次而停止的函數調用次數。Lambda 會在停止遞迴調用時立即發出此指標。若要檢視此指標,請遵循在主控台上 CloudWatch檢視指標的指示,然後選擇指標 RecursiveInvocationsDropped
。
回應遞迴迴圈偵測通知
當相同的觸發事件調用函數超過約 16 次時,Lambda 會停止該事件的下一個函數調用,以中斷遞迴循環。若要防止 Lambda 已中斷的遞迴迴圈再次發生,請執行下列動作:
-
將函數的可用並行處理降為零,這會限制所有將來的調用。
-
移除或停用正在調用函數的觸發條件或事件來源映射。
-
識別並修正程式碼瑕疵,將事件寫回叫用函數 AWS 的資源。當您使用變數來定義函數的事件來源和目標時,就會出現常見的缺陷來源。檢查兩個變數沒有使用相同的值。
此外,如果您 Lambda 函數的事件來源是 Amazon SQS佇列,請考慮在來源佇列上設定無效字母佇列。
注意
請確定在來源佇列上設定無效字母佇列,而不是在 Lambda 函數上。您在函數上設定的無效字母佇列用於佇列的非同步調用函數,而不是事件來源佇列。
如果事件來源是 Amazon SNS主題,請考慮為您的函數新增故障目的地。
將函數的可用並行處理降為零 (主控台)
開啟 Lambda 主控台中的函數頁面
。 -
選擇 函數的名稱。
-
選擇調節。
-
在調節函數對話方塊中,選擇確認。
若要移除函數的觸發條件或事件來源映射 (主控台)
開啟 Lambda 主控台中的函數頁面
。 -
選擇 函數的名稱。
-
選擇組態索引標籤,然後觸發條件。
-
在觸發條件下,選取要刪除的觸發條件或事件來源映射,然後選擇刪除。
-
在刪除觸發條件對話方塊中,選擇刪除。
若要停用函數的事件來源映射 (AWS CLI)
-
若要尋找您要停用的事件來源映射UUID的 ,請執行 AWS Command Line Interface (AWS CLI) list-event-source-mappings
命令。 aws lambda list-event-source-mappings
-
若要停用事件來源映射,請執行下列 AWS CLI update-event-source-mapping
命令。 aws lambda update-event-source-mapping --function-name
MyFunction
\ --uuida1b2c3d4-5678-90ab-cdef-EXAMPLE11111
--no-enabled
允許 Lambda 函數在遞迴迴圈中執行
如果您的設計刻意使用遞迴迴圈,您可以設定 Lambda 函數,以允許遞迴調用該函數。建議您避免在設計中使用遞迴迴圈。實作錯誤可能會導致使用 所有 AWS 帳戶可用的並行進行遞迴調用,以及從您的帳戶支付非預期的費用。
重要
如果您使用遞迴循環,請謹慎處理。實作最佳實務防護軌道,將實作錯誤的風險降至最低。若要進一步了解使用遞迴模式的最佳實務,請參閱 Serverless Land 中導致失效的遞迴模式
您可以設定函數,以允許使用 Lambda 主控台、 AWS Command Line Interface (AWS CLI) 和 PutFunctionRecursionConfig 進行遞迴循環API。您也可以在 AWS SAM 和 中設定函數的遞迴迴圈偵測設定 AWS CloudFormation。
根據預設,Lambda 會偵測並終止遞迴循環。除非設計刻意使用遞迴迴圈,否則建議您不要變更函數的預設組態。
請注意,當您設定函數以允許遞迴循環時,RecursiveInvocationsDropped
不會發出CloudWatch 指標。
您可以將函數的組態變更回預設設定,讓 Lambda 在偵測到遞迴循環時終止循環。使用 Lambda 主控台或 編輯函數的組態 AWS CLI。
Lambda 遞迴迴圈偵測的支援區域
下列 支援 Lambda 遞迴迴圈偵測 AWS 區域。
-
美國東部 (維吉尼亞北部)
-
美國東部 (俄亥俄)
-
美國西部 (加利佛尼亞北部)
-
美國西部 (奧勒岡)
-
非洲 (開普敦)
-
亞太區域 (香港)
-
亞太區域 (孟買)
-
亞太區域 (大阪)
-
亞太區域 (首爾)
-
亞太區域 (新加坡)
-
亞太區域 (雪梨)
-
亞太區域 (東京)
-
加拿大 (中部)
-
歐洲 (法蘭克福)
-
歐洲 (愛爾蘭)
-
歐洲 (倫敦)
-
歐洲 (米蘭)
-
歐洲 (巴黎)
-
歐洲 (斯德哥爾摩)
-
Middle East (Bahrain)
-
南美洲 (聖保羅)