函数计算是如何工作的?
函數計算調用鏈路
上圖展示了函數計算完整的請求和調用鏈路。函數計算是事件驅動的無服務器應用,事件驅動是說可以通過事件源自動觸發函數執行,比如當有對象上傳至 OSS 中時,自動觸發函數,對新上傳的圖片進行處理。函數計算支持豐富的事件源類型,包括日志服務、對象存儲、表格存儲、消息服務、API 網關、CDN 等。
除了事件觸發外,也可以直接通過 API/SDK 直接調用函數。調用可以分為同步調用與異步調用,當請求到達函數計算后,函數計算會為請求分配執行環境,如果是異步調用,函數計算會將請求事件存入隊列中,等待消費。
函數計算調用方式
同步調用的特性是,客戶端期待服務端立即返回計算結果。請求到達函數計算時,會立即分配執行環境執行函數。
以 API 網關為例,API 網關同步觸發函數計算,客戶端會一直等待服務端的執行結果,如果執行過程中遇到錯誤, 函數計算會將錯誤直接返回,而不會對錯誤進行重試。這種情況下,需要客戶端添加重試機制來做錯誤處理。
異步調用的特性是,客戶端不急于立即知道函數結果,函數計算將請求丟入隊列中即可返回成功,而不會等待到函數調用結束。
函數計算會逐漸消費隊列中的請求,分配執行環境,執行函數。如果執行過程中遇到錯誤,函數計算會對錯誤的請求進行重試,對函數錯誤重試三次,系統錯誤會以指數退避方式無限重試,直至成功。
異步調用適用于數據的處理,比如 OSS 觸發器觸發函數處理音視頻,日志觸發器觸發函數清洗日志,都是對延時不敏感,又需要盡可能保證任務執行成功的場景。如果用戶需要了解失敗的請求并對請求做自定義處理,可以使用 Destination 功能。
函數計算執行過程
函數計算是 Serverless 的,這不是說無服務器,而是開發者無需關心服務器,函數計算會為開發者分配實例執行函數。
如上圖所示,當函數第一次被調用的時候,函數計算需要動態調度實例、下載代碼、解壓代碼、啟動實例,得到一個可執行函數的代碼環境。然后才開始在系統分配的實例中真正地執行用戶的初始化函數,執行函數業務邏輯。這個調度實例啟動實例的過程,就是系統的冷啟動過程。
函數邏輯執行結束后,不會立即釋放掉實例,會等一段時間,如果在這段時間內有新的調用,會復用這個實例,比如上圖中的 Request 2,由于執行環境已經分配好了,Request 2 可以直接使用,所以 Request 2 就不會遇到冷啟動。
Request 2 執行結束后,等待一段時間,如果這段時間沒有新的請求分配到這個實例上,那系統會回收實例,釋放執行環境。此實例釋放后,新的請求 Request 3 來到函數計算,需要重新調度實例、下載代碼、解壓代碼,啟動實例,又會遇到冷啟動。
所以,為了減小冷啟動帶來的影響,要盡可能避免冷啟動,降低冷啟動帶來的延時。
使用預留實例可以完全避免冷啟動,預留實例是在用戶預留后就分配實例,準備執行環境;請求結束后系統也不會自動回收實例。
預留實例不由系統自動分配與回收,由用戶控制實例的生命周期,可以長駐不銷毀,這將徹底消除實例冷啟動帶來的延時毛刺,提供極致性能,也為在線應用遷移至函數計算掃清障礙。
如果業務場景不適合使用預留實例,那就要設法降低冷啟動的延時,比如降低代碼包大小,可以降低下載代碼包、解壓代碼包的時間。Initializer 函數是實例的初始化函數,Initializer 在同一實例中執行且只執行一次,所以可以將一些耗時的公共邏輯放到 Initializer 中,比如在 NAS 中加載依賴、建立連接等等。另外要盡量保持請求連續穩定,避免突發的流量,由于系統已啟動的實例不足以支撐大量的突發流量,就會帶來不可避免的冷啟動。
總結
以上是生活随笔為你收集整理的函数计算是如何工作的?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Serverless 的价值
- 下一篇: Serverless 技术选型