如果您的函數中存在耗時較長、資源消耗較大或容易出錯的邏輯,您可以使用非同步呼叫的方式,讓您的程式響應更加迅速,更加可靠地應對突發流量。當您對函數發起非同步呼叫時,無需等待函數響應,相關請求會被持久化儲存到Function Compute內部隊列中,然後被可靠地處理。本文介紹非同步呼叫的應用情境以及常見功能。
應用情境
非同步呼叫適用的情境樣本如下:
音視頻處理
使用者使用Function Compute處理音視頻業務時,涉及處理編碼、解碼或轉碼等耗時較長的任務,非同步呼叫這些任務使其在後台運行,前端無需等待,提升使用者體驗。另外,如果音視頻專案較大,需要將其分割成多個任務平行處理或者需要將一個視頻轉換為多種格式,非同步呼叫多個函數可以輕鬆實現以上平行處理需求,縮短任務處理時間。
資料ETL處理
ETL流程中,從源頭提取資料、轉換處理和載入到目標系統這三個步驟可能涉及多個獨立的操作,例如資料庫查詢、檔案讀寫或資料清洗等,採用非同步呼叫可以讓這些操作並存執行,減少處理時間,提升系統效能。而針對耗時較長的任務,例如處理大規模資料集或複雜的資料轉換,非同步呼叫允許這些任務在後台運行,前端無需等待,提升使用者體驗。
開發Web應用
Function Compute可以搭配其他雲產品快速構建Web應用。使用者在表單提交、搜尋查詢或載入內容較多的情況下,採用非同步呼叫可以避免頁面因長時間等待後端響應而出現的卡頓現象,此時使用者可以繼續與頁面的其他部分互動,而不會感受到延遲。高並發情境下,例如大量使用者同時訪問,非同步呼叫函數又可以分散請求壓力,防止服務過載。
延遲調用
針對某些情境,您提交一次非同步呼叫後,需要Function Compute對其進行延遲觸發。您可以通過調用API(SDK)實現延遲調用函數。
在代碼中添加HTTP要求標頭x-fc-async-delay
,取值範圍為(0,3600),單位為秒。Function Compute將從您觸發執行開始計算,延遲x-fc-async-delay
設定的時間後觸發函數調用。
重試策略
非同步呼叫機制提供錯誤處理和重試機制,如果某個步驟失敗,可以重新調度該任務而不影響整個流程。當函數非同步呼叫執行失敗後,Function Compute會自動進行錯誤重試。
重試機制
對於常見錯誤,系統預設的重試策略如下表所示。
錯誤類型 | 伺服器端行為 | 是否計費 | 解決方案 |
Function Compute的錯誤類型為 | 預設重試3次,或根據非同步設定次數重試。 | 按照調用次數計費。關於計費的詳細資料,請參見計費概述。 | 請自行排查您的代碼。 |
函數並發執行超上限。 | 以二進位指數退避方式重試執行5小時。當您的函數執行失敗後將在0.5秒後開始重試,後續重試執行的時間間隔將以二進位指數退避方式計算,即重試時間間隔為1秒、2秒、4秒、8秒等持續重試5小時。 | 否 | 由於阿里雲帳號(主帳號)在單個地區內預設的按量執行個體上限數為300。如果您需要提高該限制,請加入DingTalk使用者群(DingTalk群號64970014484)申請。 |
系統內部錯誤。 | 否 | 請加入DingTalk使用者群(DingTalk群號64970014484)諮詢。 | |
Function Compute資源不足。 | 否 |
配置重試策略
Function Compute支援自訂重試次數和訊息最大存活時間長度。
登入Function Compute控制台,在左側導覽列,單擊函數。
在頂部功能表列,選擇地區,然後在函數頁面,單擊目標函數。
在函數詳情頁面,選擇配置頁簽,然後在左側導覽列,選擇非同步配置,在非同步配置地區,單擊編輯。
在非同步配置面板,設定以下配置項,然後單擊部署。
結果回調
Function Compute接收非同步呼叫請求後,將請求持久化後會立即返迴響應,無需等待請求執行完成。如您需要保留執行失敗且超過最大重試次數被丟棄的請求,或通知下遊非同步呼叫結果,可以通過配置結果回調功能實現。配置非同步目標服務後,非同步呼叫請求執行完成,Function Compute根據執行結果自動回調對應的服務。
功能原理
結果回調流程如下圖所示。
適用情境
儲存丟棄的事件供後續使用
當非同步請求執行失敗,並且按照指定的策略重試後仍然失敗,Function Compute將丟棄該請求。如果您配置了失敗目標,Function Compute將自動把失敗請求的上下文資訊推送到訊息佇列 RocketMQ 版等Message Service中,以便後續處理。您也可以將目標服務設定為另一個函數,Function Compute將自動把失敗請求的上下文資訊推送到該函數,執行您自訂的錯誤處理邏輯。
自動通知下遊服務執行結果
請求執行成功後,如果您配置了成功目標,Function Compute系統會自動將成功請求的上下文資訊推送到下遊目標服務。例如,您配置了使用Function Compute實現自動解壓上傳到OSS的ZIP檔案,解壓完成後想要接收訊息通知,可採用為目標函數配置非同步呼叫結果回調目標服務。
支援的非同步呼叫目標服務
當您為函數配置了非同步呼叫目標,並且非同步呼叫後的結果符合條件時,Function Compute會將請求上下文和資料推送至對應服務。您可以針對不同函數、別名和版本配置不同的目標服務。目前支援的非同步呼叫目標服務如下:
Simple Message Queue (formerly MNS)
Function Compute
事件匯流排 EventBridge
訊息佇列 RocketMQ 版
僅支援將ApsaraMQ for RocketMQ的4.0系列執行個體配置為目標服務,不支援將5.0系列執行個體設定為目標服務。更多資訊,請參見4.x和5.x版本差異及相容性說明。
非同步呼叫目標服務的配置說明如下:
非同步呼叫目標的事件內容
Simple Message Queue (formerly MNS)、Function Compute或訊息佇列 RocketMQ 版作為函數非同步呼叫目標時,事件內容樣本如下。
{ "timestamp": 1660120276975, "requestContext": { "requestId": "xxx", "functionArn": "acs:fc:{regionid}:{accountid}:functions/xxxx", "condition": "FunctionResourceExhausted", "approximateInvokeCount": 3 }, "requestPayload": "", "responseContext": { "statusCode": 200, "functionError": "" }, "responsePayload": "" }
表 1. 參數說明
參數
說明
timestamp
調用時間戳記。
requestContext
請求上下文。
requestContext.requestId
非同步呼叫的請求ID。
requestContext.functionArn
非同步執行的函數ARN。
requestContext.condition
調用錯誤碼。
requestContext.approximateInvokeCount
非同步呼叫的執行次數。當該值大於1時,說明Function Compute對您的函數進行了重試。
requestPayload
請求函數的原始負載。
responseContext
返回上下文。
responseContext.statusCode
調用函數的返回碼(系統)。當該返回碼不為200時,說明出現了系統錯誤。
responseContext.functionError
調用錯誤資訊。
responsePayload
執行函數返回的原始負載。
事件匯流排 EventBridge作為函數非同步呼叫目標時,事件樣本如下。具體資訊,請參見事件概述。
{ "datacontenttype": "application/json", "aliyunaccountid": "143xxxx", "data": { "requestContext": { "condition": "", "approximateInvokeCount": 1, "requestId": "0fcb7f0c-xxxx", "functionArn": "acs:fc:{regionid}:{accountid}:functions/xxxx" }, "requestPayload": "", "responsePayload": "", "responseContext": { "functionError": "", "statusCode": 200 }, "timestamp": 1660120276975 }, "subject": "acs:fc:{regionid}:{accountid}:functions/xxxx", "source": "acs:fc", "type": "fc:AsyncInvoke:succeeded", "aliyunpublishtime": "2021-01-03T09:44:31.233Asia/Shanghai", "specversion": "1.0", "aliyuneventbusname": "xxxxxxx", "id": "ecc4865xxxxxx", "time": "2021-01-03T01:44:31Z", "aliyunregionid": "cn-shanghai-vpc", "aliyunpublishaddr": "199.99.xxx.xxx" }
負載限制
支援的非同步呼叫目標服務負載的最大限制如下:
Simple Message Queue (formerly MNS):64 KB
Function Compute:128 KB
事件匯流排 EventBridge:64 KB
訊息佇列 RocketMQ 版:4 MB
避免迴圈調用
當您在配置非同步執行目標時,請確保不要出現迴圈調用的情況。例如,您為函數A配置了成功調用時的非同步目標為函數B,為函數B配置了成功調用時的非同步目標為函數A。當您非同步觸發函數A並且執行成功後,則可能出現A到B,再到A的迴圈調用的情況。
配置非同步呼叫目標服務
登入Function Compute控制台,在左側導覽列,單擊函數。
在頂部功能表列,選擇地區,然後在函數頁面,單擊目標函數。
在函數詳情頁面,選擇配置頁簽,在左側導覽列,選擇非同步配置,按需配置參數資訊。
配置成功目標
在成功目標地區,單擊編輯。
在成功目標面板,成功時調用其他服務選擇啟用,然後配置當函數成功執行後將需要發送結果的目標雲端服務。參數資訊如下:
參數
說明
目標服務
Function Compute。當目標服務選擇的是Function Compute時,需配置以下參數資訊:
函數名稱:指定目標函數的名稱。
版本或別名:指定函數的別名或版本。
Simple Message Queue (formerly MNS)。當目標服務選擇的是Simple Message Queue (formerly MNS)時,需配置以下參數資訊:
目標類型:按需選擇目標類型,取值為:
隊列:
隊列模型提供高可靠、高並發的一對一消費模型,即隊列中的每一條訊息都只能夠被某一個消費者消費。
主題:
主題模型提供一對多的發布訂閱模型,支援訊息通知。
隊列:選擇Simple Message Queue (formerly MNS)的隊列名稱。當目標類型選擇的是隊列時需設定此參數。
主題:選擇Simple Message Queue (formerly MNS)的主題名稱。當目標類型選擇的是主題時需設定此參數。
訊息佇列 RocketMQ 版,當目標服務選擇的是訊息佇列 RocketMQ 版時,需配置以下參數資訊:
執行個體:選擇目標執行個體。
Topic:選擇目標Topic。
事件匯流排 EventBridge。當目標服務選擇的是事件匯流排 EventBridge時,需指定自訂事件匯流排。
單擊部署。
配置失敗目標
在失敗目標地區,單擊編輯。
在失敗目標面板,失敗時調用其他服務選擇啟用,然後配置當函數執行失敗後需要發送訊息的目標雲端服務。
配置失敗目標的參數,請參見上方配置成功目標參數說明。
單擊部署。
回調失敗的處理
當函數角色無目標服務存取權限或目標服務不可用時,回調目標服務可能會失敗。Function Compute提供了相關的指標及日誌,您可以根據需要進行相應處理。常見的錯誤及系統行為如下所示:
錯誤碼 | 錯誤原因 | 系統行為 |
5xx | 限流或內容錯誤等。 | Function Compute系統內部按指數退避自動重試。初始稍候再試為500毫秒,最大重試時間長度為30分鐘。 |
4xx | 無許可權、請求參數不正確(如目標服務的資源已被刪除)或請求訊息體超過目標服務限額等。 | 返回錯誤並記錄錯誤資訊。 |
結果回調指標
當回調目標服務失敗後,Function Compute會記錄相應指標並展示到控制台。您可以登入Function Compute控制台,在左側導覽列選擇 ,然後在函數名稱列表單擊目標函數名稱,查看函數維度指標情況。
指標名稱 | 描述 |
目標觸發失敗(FunctionDestinationErrors) | 函數非同步呼叫配置Destination時,函數執行中觸發目標失敗的請求數。按1分鐘或1小時粒度統計求和。 |
目標觸發成功(FunctionDestinationSucceed) | 函數非同步呼叫配置Destination時,函數執行中觸發目標成功的請求數。按1分鐘或1小時粒度統計求和。 |
更多監控指標,請參見監控指標。
常見問題
如何觸發函數的非同步呼叫?
您可以通過以下方式對Function Compute的函數發起一次非同步呼叫。
登入Function Compute控制台,找到目標函數,然後在測試頁簽,勾選我想通過非同步方式進行調用。
調用InvokeFunction - 調用函數介面,設定參數
x-fc-invocation-type
的值為Async。使用Serverless Devs工具配置非同步呼叫,設定參數
invocation-type
的值為Async,詳情請參見調用函數。建立支援非同步呼叫的觸發器非同步觸發函數,詳情請參見事件觸發。
後續操作
如果您希望獲得函數非同步請求各個階段的狀態,可通過開啟任務模式來實現,具體資訊,請參見非同步任務。