「無服務器架構」Openwhisk 系統概覽

OpenWhisk是一個事件驅動的計算平臺,也稱為無服務器計算或功能即服務(FaaS),用於響應事件或直接調用而運行代碼。 下圖顯示了高級OpenWhisk體系結構。


「無服務器架構」Openwhisk 系統概覽


事件的示例包括數據庫記錄的更改,超過特定溫度的IoT傳感器讀數,將新代碼提交到GitHub存儲庫或來自Web或移動應用程序的簡單HTTP請求。來自外部和內部事件源的事件通過觸發器進行傳遞,並且規則允許操作對這些事件做出反應。

操作可以是小的代碼片段(支持JavaScript,Swift和許多其他語言),也可以是嵌入在Docker容器中的自定義二進制代碼。每當觸發觸發器時,OpenWhisk中的操作就會立即部署並執行。觸發次數越多,調用的動作越多。如果沒有觸發觸發器,則不會運行任何操作代碼,因此沒有成本。

除了將動作與觸發器相關聯之外,還可以通過使用OpenWhisk API,CLI或iOS SDK直接調用動作。一組動作也可以鏈接在一起,而無需編寫任何代碼。依次調用鏈中的每個動作,並將一個動作的輸出作為輸入傳遞到序列中的下一個動作。

對於傳統的長期運行的虛擬機或容器,通常的做法是部署多個VM或容器以抵禦單個實例的故障。但是,OpenWhisk提供了一種替代模型,沒有與彈性相關的成本開銷。按需執行操作可提供固有的可伸縮性和最佳利用率,因為正在運行的操作數始終與觸發率匹配。此外,開發人員現在只關注代碼,而不必擔心監視,修補和保護基礎服務器,存儲,網絡和操作系統基礎結構。

與其他服務和事件提供程序的集成可以隨包一起添加。一攬子計劃是一堆提要和操作。提要是一段代碼,用於配置外部事件源以觸發觸發事件。例如,使用Cloudant變更Feed創建的觸發器將配置服務,以在每次文檔被修改或添加到Cloudant數據庫時觸發該觸發器。包中的動作表示服務提供者可以提供的可重用邏輯,以便開發人員不僅可以將服務用作事件源,還可以調用該服務的API。

現有的軟件包目錄提供了一種快速的方法來增強具有有用功能的應用程序,並訪問生態系統中的外部服務。啟用了OpenWhisk的外部服務的示例包括Cloudant,The Weather Company,Slack和GitHub。

OpenWhisk的工作方式


作為一個開源項目,OpenWhisk站在Nginx,Kafka,Docker,CouchDB等巨頭的肩膀上。所有這些組件共同構成了“無服務器基於事件的編程服務”。為了更詳細地解釋所有組件,讓我們跟蹤動作在系統發生時的調用。無服務器引擎的核心工作是OpenWhisk中的調用:執行用戶輸入到系統中的代碼,並返回執行結果。

創建動作


為了提供一些上下文說明,我們首先在系統中創建一個動作。 我們將在稍後瀏覽系統時使用該操作來解釋概念。 以下命令假定已正確設置OpenWhisk CLI。

首先,我們將創建一個包含以下代碼的action.js文件,該代碼會將“ Hello World”打印到標準輸出,並在鍵“ hello”下返回一個包含“ world”的JSON對象。

function main() { console.log('Hello World'); return { hello: 'world' }; }

我們使用創建該動作。

wsk action create myAction action.js

做完了 現在我們實際上要調用該動作:

wsk action invoke myAction --result

內部處理流程


OpenWhisk幕後實際上發生了什麼?

「無服務器架構」Openwhisk 系統概覽

進入系統:nginx


第一:OpenWhisk的面向用戶的API完全基於HTTP,並採用RESTful設計。 因此,通過wsk CLI發送的命令實際上是針對OpenWhisk系統的HTTP請求。 上面的特定命令大致翻譯為:

POST /api/v1/namespaces/$userNamespace/actions/myAction Host: $openwhiskEndpoint

注意這裡的$ userNamespace變量。用戶可以訪問至少一個名稱空間。為了簡單起見,假設用戶擁有放置myAction的名稱空間。

進入系統的第一個入口是通過nginx,“ HTTP和反向代理服務器”。它主要用於SSL終止並將適當的HTTP調用轉發到下一個組件。

進入系統:控制器


對我們的HTTP請求沒有做很多事情,nginx將其轉發到Controller,這是我們通過OpenWhisk進行的下一個組件。它是實際REST API(基於Akka和Spray)的基於Scala的實現,因此可以用作用戶可以做的所有事情的接口,包括在OpenWhisk中對實體的CRUD請求和動作的調用(這就是我們的現在正在做)。

控制器首先消除用戶要做什麼的歧義。它基於您在HTTP請求中使用的HTTP方法來執行此操作。根據上面的翻譯,用戶向現有動作發出POST請求,控制器將其轉換為動作的調用。

鑑於控制器的中心作用(因此得名),以下步驟在一定程度上都會涉及它。


現在,控制器將驗證您的身份(身份驗證),以及您是否有權對實體執行您想做的事情(授權)。將根據CouchDB實例中的所謂主題數據庫驗證請求中包含的憑據。

在這種情況下,將檢查用戶是否存在於OpenWhisk的數據庫中,並檢查該用戶是否有權調用動作myAction,我們假設該動作是用戶擁有的命名空間中的動作。後者有效地賦予了用戶調用該操作的特權,這是他希望執行的操作。

一切正常後,門打開,進入下一階段的處理。

採取行動:再次CouchDB…


由於Controller現在確定允許用戶進入並具有調用其操作的特權,因此它實際上是從CouchDB的拂數據庫中加載了此操作(在本例中為myAction)。

動作記錄主要包含要執行的代碼(如上所示)和要傳遞給動作的默認參數,並與實際調用請求中包含的參數合併。它還包含執行時對其施加的資源限制,例如允許使用的內存。

在這種特殊情況下,我們的操作沒有任何參數(該函數的參數定義是一個空列表),因此我們假設我們沒有設置任何默認參數,也沒有向該操作發送任何特定的參數,從這個角度來看,最瑣碎的情況。

誰來執行該操作:負載均衡器


作為控制器一部分的負載均衡器通過連續檢查其運行狀況來全局查看系統中可用的執行器。這些執行者被稱為祈求者。知道哪些可用的調用程序的負載均衡器會選擇其中之一來調用請求的操作。

請排隊:Kafka


從現在開始,您發送的調用請求可能主要發生兩件事:

  • 系統可能崩潰,丟失您的調用。
  • 系統可能會承受如此沉重的負擔,以至於調用需要先等待其他調用才能完成。

兩者的答案都是Kafka,“一個高吞吐量,分佈式,發佈-訂閱消息系統”。 Controller和Invoker僅通過Kafka緩衝和保留的消息進行通信。這樣就減輕了控制器和調用者的內存緩衝負擔,並冒出OutOfMemoryException的風險,同時還確保在系統崩潰的情況下不會丟失消息。

為了調用該動作,控制器將消息發佈到Kafka,其中包含要調用的動作和傳遞給該動作的參數(在本例中為無)。該消息發送給控制器從上方從可用調用者列表中選擇的調用者。

Kafka確認收到消息後,將使用ActivationId響應對用戶的HTTP請求。用戶稍後將使用它來訪問此特定調用的結果。請注意,這是一個異步調用模型,在該模型中,一旦系統接受了調用某個動作的請求,HTTP請求就會終止。可以使用同步模型(稱為阻塞調用),但本文不會介紹。

實際上已經在調用代碼了:調用者


調用程序是OpenWhisk的心臟。調用者的職責是調用一個動作。它也在Scala中實現。但是還有更多的東西。為了以隔離和安全的方式執行操作,它使用Docker。

Docker用於為我們以快速,隔離和受控的方式調用的每個動作設置一個新的自封裝環境(稱為容器)。簡而言之,對於每個動作調用,都會產生一個Docker容器,該動作代碼被注入,並使用傳遞給它的參數執行該操作代碼,獲得結果,該容器被銷燬。這也是進行大量性能優化以減少開銷和縮短響應時間的地方。

在我們的特定情況下,由於手頭有一個基於Node.js的操作,Invoker將啟動一個Node.js容器,從myAction注入代碼,不帶任何參數運行它,提取結果,保存日誌並銷燬再次使用Node.js容器。

存儲結果:再次CouchDB


由於調用者獲得了結果,因此將其存儲為激活數據庫,作為上面進一步提到的ActivationId下的激活。激活數據庫位於CouchDB中。

在我們的特定情況下,Invoker從操作中獲取返回的JSON對象,獲取Docker編寫的日誌,將它們全部放入激活記錄中並將其存儲到數據庫中。大致如下所示:

{ "activationId": "31809ddca6f64cfc9de2937ebd44fbb9", "response": { "statusCode": 0, "result": { "hello": "world" } }, "end": 1474459415621, "logs": [ "2016-09-21T12:03:35.619234386Z stdout: Hello World" ], "start": 1474459415595, }

注意記錄如何包含返回的結果和寫入的日誌。 它還包含操作調用的開始時間和結束時間。 激活記錄中有更多字段,為簡化起見,這是簡化版本。

現在,您可以再次使用REST API(再次從步驟1開始)以獲取激活,從而獲得操作結果。 為此,您可以使用:

wsk activation get 31809ddca6f64cfc9de2937ebd44fbb9

摘要


我們已經瞭解了一個簡單的wsk動作如何調用myAction貫穿OpenWhisk系統的不同階段。 系統本身主要僅包含兩個自定義組件,即Controller和Invoker。 其他一切都已經存在,由開源社區中如此眾多的人開發。

您可以在以下主題中找到有關OpenWhisk的其他信息:

  • 實體名稱
  • 動作語義
  • 限度
  • REST API

原文:https://github.com/apache/openwhisk/blob/master/docs/about.md

本文:http://jiagoushi.pro/node/899

討論:請加入知識星球【首席架構師圈】或者微信圈子【首席架構師圈】


分享到:


相關文章: