如果您的函數中存在耗時較長、資源消耗較大或容易出錯的邏輯,您可以使用異步調用的方式,讓您的程序響應更加迅速,更加可靠地應對突發流量。當您對函數發起異步調用時,無需等待函數響應,相關請求會被持久化保存到函數計算內部隊列中,然后被可靠地處理。本文介紹異步調用的應用場景以及常見功能。
應用場景
異步調用適用的場景示例如下:
音視頻處理
用戶使用函數計算處理音視頻業務時,涉及處理編碼、解碼或轉碼等耗時較長的任務,異步調用這些任務使其在后臺運行,前端無需等待,提升用戶體驗。另外,如果音視頻項目較大,需要將其分割成多個任務并行處理或者需要將一個視頻轉換為多種格式,異步調用多個函數可以輕松實現以上并行處理需求,縮短任務處理時間。
數據ETL處理
ETL流程中,從源頭提取數據、轉換處理和加載到目標系統這三個步驟可能涉及多個獨立的操作,例如數據庫查詢、文件讀寫或數據清洗等,采用異步調用可以讓這些操作并行執行,減少處理時間,提升系統性能。而針對耗時較長的任務,例如處理大規模數據集或復雜的數據轉換,異步調用允許這些任務在后臺運行,前端無需等待,提升用戶體驗。
開發Web應用
函數計算可以搭配其他云產品快速構建Web應用。用戶在表單提交、搜索查詢或加載內容較多的情況下,采用異步調用可以避免頁面因長時間等待后端響應而出現的卡頓現象,此時用戶可以繼續與頁面的其他部分交互,而不會感受到延遲。高并發場景下,例如大量用戶同時訪問,異步調用函數又可以分散請求壓力,防止服務過載。
延遲調用
針對某些場景,您提交一次異步調用后,需要函數計算對其進行延遲觸發。您可以通過調用API(SDK)實現延遲調用函數。
在代碼中添加HTTP請求頭x-fc-async-delay
,取值范圍為(0,3600),單位為秒。函數計算將從您觸發執行開始計算,延遲x-fc-async-delay
設置的時間后觸發函數調用。
重試策略
異步調用機制提供錯誤處理和重試機制,如果某個步驟失敗,可以重新調度該任務而不影響整個流程。當函數異步調用執行失敗后,函數計算會自動進行錯誤重試。
重試機制
對于常見錯誤,系統默認的重試策略如下表所示。
錯誤類型 | 服務器端行為 | 是否計費 | 解決方案 |
函數計算的錯誤類型為 | 默認重試3次,或根據異步設置次數重試。 | 按照調用次數計費。關于計費的詳細信息,請參見計費概述。 | 請自行排查您的代碼。 |
函數并發執行超上限。 | 以二進制指數退避方式重試執行5小時。當您的函數執行失敗后將在0.5秒后開始重試,后續重試執行的時間間隔將以二進制指數退避方式計算,即重試時間間隔為1秒、2秒、4秒、8秒等持續重試5小時。 | 否 | 單個阿里云賬號(主賬號)在單個地域內總實例數默認限制為100,實際數值以配額中心為準,如果您需要提高該限制,請前往配額中心申請。 |
系統內部錯誤。 | 否 | 請加入釘釘用戶群(釘釘群號64970014484)咨詢。 | |
函數計算資源不足。 | 否 |
配置重試策略
函數計算支持自定義重試次數和消息最大存活時長。
登錄函數計算控制臺,在左側導航欄,單擊函數。
在頂部菜單欄,選擇地域,然后在函數頁面,單擊目標函數。
在函數詳情頁面,選擇配置頁簽,然后在左側導航欄,選擇異步配置,在異步配置區域,單擊編輯。
在異步配置面板,設置以下配置項,然后單擊部署。
結果回調
函數計算接收異步調用請求后,將請求持久化后會立即返回響應,無需等待請求執行完成。如您需要保留執行失敗且超過最大重試次數被丟棄的請求,或通知下游異步調用結果,可以通過配置結果回調功能實現。配置異步目標服務后,異步調用請求執行完成,函數計算根據執行結果自動回調對應的服務。
功能原理
結果回調流程如下圖所示。
適用場景
保存丟棄的事件供后續使用
當異步請求執行失敗,并且按照指定的策略重試后仍然失敗,函數計算將丟棄該請求。如果您配置了失敗目標,函數計算將自動把失敗請求的上下文信息推送到消息隊列 RocketMQ 版等消息服務中,以便后續處理。您也可以將目標服務設置為另一個函數,函數計算將自動把失敗請求的上下文信息推送到該函數,執行您自定義的錯誤處理邏輯。
自動通知下游服務執行結果
請求執行成功后,如果您配置了成功目標,函數計算系統會自動將成功請求的上下文信息推送到下游目標服務。例如,您配置了使用函數計算實現自動解壓上傳到OSS的ZIP文件,解壓完成后想要接收消息通知,可采用為目標函數配置異步調用結果回調目標服務。
支持的異步調用目標服務
當您為函數配置了異步調用目標,并且異步調用后的結果符合條件時,函數計算會將請求上下文和數據推送至對應服務。您可以針對不同函數、別名和版本配置不同的目標服務。目前支持的異步調用目標服務如下:
輕量消息隊列(原 MNS)
函數計算
事件總線 EventBridge
消息隊列 RocketMQ 版
僅支持將云消息隊列 RocketMQ 版的4.0系列實例配置為目標服務,不支持將5.0系列實例設置為目標服務。更多信息,請參見4.x和5.x版本差異及兼容性說明。
異步調用目標服務的配置說明如下:
異步調用目標的事件內容
輕量消息隊列(原 MNS)、函數計算或消息隊列 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時,說明函數計算對您的函數進行了重試。
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" }
負載限制
支持的異步調用目標服務負載的最大限制如下:
輕量消息隊列(原 MNS):64 KB
函數計算:128 KB
事件總線 EventBridge:64 KB
消息隊列 RocketMQ 版:4 MB
避免循環調用
當您在配置異步執行目標時,請確保不要出現循環調用的情況。例如,您為函數A配置了成功調用時的異步目標為函數B,為函數B配置了成功調用時的異步目標為函數A。當您異步觸發函數A并且執行成功后,則可能出現A到B,再到A的循環調用的情況。
配置異步調用目標服務
登錄函數計算控制臺,在左側導航欄,單擊函數。
在頂部菜單欄,選擇地域,然后在函數頁面,單擊目標函數。
在函數詳情頁面,選擇配置頁簽,在左側導航欄,選擇異步配置,按需配置參數信息。
配置成功目標
在成功目標區域,單擊編輯。
在成功目標面板,成功時調用其他服務選擇啟用,然后配置當函數成功執行后將需要發送結果的目標云服務。參數信息如下:
參數
說明
目標服務
函數計算。當目標服務選擇的是函數計算時,需配置以下參數信息:
函數名稱:指定目標函數的名稱。
版本或別名:指定函數的別名或版本。
輕量消息隊列(原 MNS)。當目標服務選擇的是輕量消息隊列(原 MNS)時,需配置以下參數信息:
目標類型:按需選擇目標類型,取值為:
隊列:
隊列模型提供高可靠、高并發的一對一消費模型,即隊列中的每一條消息都只能夠被某一個消費者消費。
主題:
主題模型提供一對多的發布訂閱模型,支持消息通知。
隊列:選擇輕量消息隊列(原 MNS)的隊列名稱。當目標類型選擇的是隊列時需設置此參數。
主題:選擇輕量消息隊列(原 MNS)的主題名稱。當目標類型選擇的是主題時需設置此參數。
消息隊列 RocketMQ 版,當目標服務選擇的是消息隊列 RocketMQ 版時,需配置以下參數信息:
實例:選擇目標實例。
Topic:選擇目標Topic。
事件總線 EventBridge。當目標服務選擇的是事件總線 EventBridge時,需指定自定義事件總線。
單擊部署。
配置失敗目標
在失敗目標區域,單擊編輯。
在失敗目標面板,失敗時調用其他服務選擇啟用,然后配置當函數執行失敗后需要發送消息的目標云服務。
配置失敗目標的參數,請參見上方配置成功目標參數說明。
單擊部署。
回調失敗的處理
當函數角色無目標服務訪問權限或目標服務不可用時,回調目標服務可能會失敗。函數計算提供了相關的指標及日志,您可以根據需要進行相應處理。常見的錯誤及系統行為如下所示:
錯誤碼 | 錯誤原因 | 系統行為 |
5xx | 限流或內容錯誤等。 | 函數計算系統內部按指數退避自動重試。初始重試間隔為500毫秒,最大重試時長為30分鐘。 |
4xx | 無權限、請求參數不正確(如目標服務的資源已被刪除)或請求消息體超過目標服務限額等。 | 返回錯誤并記錄錯誤信息。 |
結果回調指標
當回調目標服務失敗后,函數計算會記錄相應指標并展示到控制臺。您可以登錄函數計算控制臺,在左側導航欄選擇 ,然后在函數名稱列表單擊目標函數名稱,查看函數維度的指標情況。
指標名稱 | 描述 |
目標觸發失敗(FunctionDestinationErrors) | 函數異步調用配置Destination時,函數執行中觸發目標失敗的請求數。按1分鐘或1小時粒度統計求和。 |
目標觸發成功(FunctionDestinationSucceed) | 函數異步調用配置Destination時,函數執行中觸發目標成功的請求數。按1分鐘或1小時粒度統計求和。 |
更多監控指標,請參見監控指標。
常見問題
如何觸發函數的異步調用?
您可以通過以下方式對函數計算的函數發起一次異步調用。
登錄函數計算控制臺,找到目標函數,然后在測試頁簽,勾選我想通過異步的方式進行調用。
調用InvokeFunction - 調用函數接口,設置參數
x-fc-invocation-type
的值為Async。使用Serverless Devs工具配置異步調用,設置參數
invocation-type
的值為Async,詳情請參見調用函數。創建支持異步調用的觸發器異步觸發函數,詳情請參見事件觸發。
后續操作
如果您希望獲得函數異步請求各個階段的狀態,可通過開啟任務模式來實現,具體信息,請參見異步任務。