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

OpenWhisk 是一個事件驅動的計算平臺,也稱爲無服務器計算或功能即服務(FaaS),用於響應事件或直接調用而運行代碼。下圖顯示了高級 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 幕後實際上發生了什麼?

進入系統: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

現在,控制器將驗證您的身份(身份驗證),以及您是否有權對實體執行您想做的事情(授權)。將根據 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 的其他信息:

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

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

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

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/1V0w530IanW7bvxm5pO7ZA