函數組合的 N 種模式

隨着以函數即服務(Function as a Service)爲表明的無服務器計算(Serverless)的普遍使用,不少用戶遇到了涉及多個函數的場景,須要組合多個函數來共同完成一個業務目標,這正是微服務「分而治之,合而用之」的精髓所在。本文以阿里雲函數計算爲例,試圖全面介紹函數組合的常見模式和使用場景,但願有助於選擇合適的解決方案。html

雖然本文主要介紹的是函數組合,可是基本思想也可用於服務組合。git

函數同步調用函數

746005ab344914991609f2d30e065701

在這種模式裏,函數直接調用 InvokeFunction 同步 API 執行一個或者多個函數,等待被調用函數返回結果,而後繼續執行。這是一個有些爭議的模式,不使用同步調用一般有如下緣由:github

  1. 從費用的角度:因爲函數計算按照函數實際執行時間收費,調用者在等待被調用函數返回前也會產生必定費用。
  2. 執行時長限制:因爲函數最長執行10分鐘,這就決定了調用的其它函數執行時間之和有限。
  3. 從容錯的角度:被調用者出錯會直接影響調用者,若是這個調用鏈很長,則這種錯誤會一直蔓延到最初的調用者,容錯性較差。同時因爲執行時長限制,調用者一般不容易針對錯誤作長時間重試。

上面的理由是在有些場景下成立的,可是微服務最經典最多見的組合方式就是同步調用,函數做爲微服務的一種實現方式,這種同步調用的需求是不可迴避的,在有些場景下采用同步調用模式是值得考慮的,這些場景包括:數據庫

  1. 調用者函數須要被調用函數執行結果作後續處理或者返回給客戶端。
  2. 函數執行時間較短,最好在毫秒到秒級別。
  3. 調用者是無狀態的,不須要針對被調用者的錯誤作複雜重試。

在這種模式裏,調用者一般不須要作複雜的計算,主要時間花在調用函數和等待返回上,所以調用者函數能夠設置較小的內存,以減小費用;調用者還能夠根據業務需求緩存調用結果,減小對其它函數的調用,從而節約費用和加強容錯性。api

函數經過 API 網關調用函數

b805552a8de08160fe1852fb2fdb1c10

與函數直接調用函數不一樣,這裏被調用函數在 API 網關後面,使它看起來更像一個微服務。這種模式的限制和使用場景跟上面的直接調用模式相似,不一樣之處是 API 網關提供了一些額外的能力,好比認證和限流等。若是被調用者要根據某些業務信息對請求作處理,則使用 API 網關是一個好的選擇。固然,使用 API 網關也帶來了額外的延遲和費用,若是不須要使用 API 網關提供的能力,則讓函數直接調用函數是一個更好的選擇。數組

函數異步調用函數

be45bc3b11d5822a224b6f2da7778a43

在這種模式裏,函數執行完自身業務邏輯後,調用 InvokeFunction 異步 API 通知其它函數執行並退出,它不關心被調用函數是否執行完成。函數計算的 InvokeFunction 異步 API 是經過隊列實現的,異步請求首先被寫入隊列,而後有一個組件從隊列裏消費請求,執行相應函數。這種模式的優點和使用場景有:緩存

  1. 對執行延遲不敏感的場景,適合削峯填谷,減輕對依賴服務的壓力。函數計算會根據用戶的資源使用狀況動態的調整隊列的處理速度,平滑請求對系統的壓力,固然這種平滑也可能會致使一些請求被延緩執行。
  2. 調用者能夠較容易的觸發多個被調用者執行,實現 Fan-Out 模式。好比一個視頻處理函數能夠異步調用多個函數來分別將視頻轉換成不一樣格式。
  3. 因爲每一個函數所花時間都用在執行業務邏輯,而非等待其它函數返回上,沒有產生沒必要要的費用。

這種模式有以下侷限性:安全

  1. 調用者顯然沒法知道被調用者的執行結果。
  2. 被調用者之間最好是獨立執行的,不須要相互協調,不然經過數據庫來協調執行會增長複雜度。例如,上面提到的視頻處理函數調用多個函數分別將視頻轉換成不一樣格式,若是須要在全部的視頻轉換完成後發郵件通知用戶,這就須要等待全部的轉換函數執行結束。這種等待多個事件發生的模式叫作 Fan-In,不適合經過這種異步調用模式實現。

基於消息主題的函數調用

a81b47c9c3e73fdff6e3e41c035cfb23

與上面的模式須要指定被調用函數不一樣,基於事件觸發模式讓調用者只須要發佈消息,不關心誰去消費消息。在消息服務(MNS)中,主題是發佈消息的目的地,發佈者能夠經過 PublishMessage API 向主題發佈消息, 主題的訂閱者會接收到發佈到主題上的消息,MNS 與函數計算服務的集成讓函數能夠直接做爲訂閱者,簡化了消息處理應用的開發和運維代價。服務器

和上面的異步調用模式相比,基於消息主題的調用模式有如下優點:網絡

  1. 進一步解耦函數調用。調用者無需知道被調用者的信息,只須要約定消息的格式。
  2. 得益於一個主題能夠對應多個訂閱者,更容易實現 Fan-Out 模式。發佈者只須要發佈一條消息就能觸發多個函數。在上面的異步調用方式中,調用者仍須要顯式調用一個或者多個函數來觸發執行。
  3. 雖然主題模式本質上是消息服務推送消息給訂閱者,不會考慮訂閱者的承載能力,可是因爲阿里雲消息服務是經過 InvokeFunction 異步 API 調用函數,所以這種模式也具有基於消息隊列模式的削峯填谷能力。

這種模式的侷限性跟異步調用函數相似:

  1. 很難支持等待多個事件觸發一個函數的場景(Fan-In)。
  2. 須要作必定工做才能跟蹤多個函數執行狀態。
  3. 很難限制單個函數的執行時間或者全部函數的總執行時間。
  4. 沒法針對函數執行錯誤定義重試策略。

基於對象存儲服務的函數調用

97c87db6ed57833eebdab5aa2f578574

函數計算服務除了集成了消息主題之外,還集成了對象存儲服務 (OSS),表格存儲等其它事件源,這些事件源服務一樣能夠做爲鏈接函數的渠道。好比,一個非函數應用對 OSS 對象操做(建立,刪除等)後,一般須要其它渠道(好比消息服務)通知其它應用作後續處理,而因爲 OSS 和函數計算的集成,只需簡單配置,這些事件就能夠直接傳遞給自定義函數,而不須要額外渠道再傳遞信息,簡化了數據處理流水線的開發和運維代價。

基於日誌庫的函數調用

05bbc670f1354950ad39f6465112c673

日誌服務的日誌庫是一個流(Stream)存儲,生產者寫入數據到日誌庫,消費者讀出數據並處理。日誌服務和函數計算的集成,使得消費者能夠是函數,從而實現了經過流存儲來協調函數調用。上面全部模式都是調用者顯式或者隱式的觸發一個或多個被調用函數執行,而這裏生產者函數寫入的數據不必定會馬上被消費者函數處理,日誌服務會根據用戶配置將多個數據批量推送給消費者函數。

這種模式有如下優點:

  1. 日誌服務會針對每一個分區(Shard)並行調用函數,若是數據吞吐較大,能夠經過擴展分區來提升消費吞吐能力。
  2. 日誌服務給函數推送的同一分區數據是串行的和嚴格保序的,在老的數據沒有消費成功前不會推送新的數據。
  3. 日誌服務會持續推送相同數據到函數直到函數消費數據後返回正常。

基於函數工做流的函數組合

9bad3110cdaf618492064cde03723413

函數工做流(Function Flow,簡稱 FnF)是一個用來協調多個分佈式任務執行的全託管 Serverless 雲服務,簡化了開發和運行業務流程所須要的任務協調、狀態管理以及錯誤處理等繁瑣工做,讓用戶更好的專一業務邏輯開發。能夠說函數工做流是轉爲函數組合而生,有效的解決了上面幾種異步組合模式的侷限性。

上面的全部模式都是經過點對點的方式來組合函數,而函數工做流是一個集中的協調者,函數以前再也不直接或者間接通訊,全部的觸發都是由函數工做流發起,不一樣函數的輸入和輸出是經過函數工做流來傳遞。所以,這種方式下的函數代碼全是業務邏輯相關,沒有上面模式裏的發送主題消息,或者調用其它函數的邏輯,實現更加清晰。

函數工做流有如下優點:

  1. 服務編排能力:能夠將流程邏輯與任務執行分開,支持多種控制原語,好比順序執行多個函數,根據函數執行結果選擇執行其它函數,讓多個函數並行處理數據,或者讓一個函數並行處理一組數據等,以及上面的 Fan-In 模式。函數工做流還內置了錯誤重試和捕獲能力,節省了編寫編排代碼的時間。
  2. 支持長流程:不管是毫秒級仍是長達一年的業務流程,FnF 均可以跟蹤整個流程,確保流程執行完成。
  3. 流程狀態管理:FnF 會管理流程執行中的全部狀態,包括跟蹤它所處的執行步驟,以及存儲在步驟之間的輸入輸出。您無需本身管理流程狀態,也沒必要將複雜的狀態管理構建到任務中。
  4. 協調分佈式組件:FnF 可以協調運行在不一樣架構,不一樣網絡,不一樣語言實現的分佈式應用。不管是私有云、專有云的應用想要平滑過渡到混合雲、公共雲,仍是單體架構的應用想要演進到微服務架構,FnF 都能在其中發揮協調做用。函數工做流經過集成消息隊列,讓任何能夠訪問消息隊列的應用也能夠做爲流程一部分,相互協做,共同完成業務目標。
  5. 可視化監控:FnF 提供了可視化界面來協助定義流程和查看執行狀態,方便您快速識別故障位置,並快速排除故障問題。
  6. 運維全託管和按需付費:FnF 讓您從基礎設施維護中解放出來,提供了安全的、高可用的、高容錯的彈性服務。用戶只需支付步驟轉換費用,不使用不產生費用。

函數工做流目前還不支持同步調用方式,若是您有同步調用需求,歡迎聯繫咱們(見文章最後釘釘客戶羣)。

總結

總的來講,上面的組合模式能夠分爲同步和異步兩種,在場景適合的狀況下優先選擇異步模式,享受異步模式帶來的鬆耦合,高容錯等特性,不然使用同步模式。在異步模式中,若是須要編寫複雜的組合邏輯,支持可靠的重試,把控整個流程,則推薦使用函數工做流,不然使用消息主題或者其它事件源服務來組合函數。

上面的模式也不是割裂的,它們在有些場景下能夠搭配使用,好比有時候基於對象存儲服務的調用須要觸發多個函數,這就能夠結合使用 OSS 的事件觸發和函數工做流;又好比函數工做流經過消息隊列將任務發送給更普遍的消費者,觸達函數計算沒法觸達的地方。

最後,歡迎加入函數工做流和函數計算客戶羣。

1571936661683
1571970520181

阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,作最懂雲原生開發者的技術圈。」

相關文章
相關標籤/搜索