如何將微服務體系結構運用于嵌入式系統?
譯文譯者 | 布加迪
審校 | 重樓
微服務體系結構是Facebook、Netflix和優步等跨國企業發布的分布式應用系統的基礎。精細化隔離服務,然后將它們聚合起來協同工作,這使得分布式系統比單體式系統更易于管理。但是對于嵌入式系統而言,情況就有點不同了。
不像在數據中心內和跨數據中心運行的面向微服務的體系結構(MOA),嵌入式系統往往在硬件和用例方面是專用的——比如運行在工業裝配廠中操作的一群機器人工人或控制自動駕駛汽車。
面向微服務的體系結構可以運用于這些類型的環境,但是需要特別注意出現問題時,您不能僅僅啟動另一個容器來替換失效的容器。要做的工作不止這些。
為嵌入式系統編寫面向微服務的體系結構需要一種不同的設計和實施方法。
面向微服務的體系結構簡介
在深入討論將MOA運用于嵌入式系統的細節之前,不妨先大致了解這種體系結構的基本要素。
面向微服務的體系結構旨在將應用程序的行為分解為一群獨立存在但一致行動的離散服務。MOA的工作方式是將離散服務分發到眾多遠程位置。
通常,這些服務使用一種眾所周知的傳輸協議(比如TCP、UDP或HTTP)發送和接收數據。某種類型的組織、前端客戶端機制(比如在桌面或移動設備上運行的網頁或原生代碼)將各種服務聚集在一起,形成整個應用程序的統一表示。然而如前所述,組成MOA的每個服務都是遠程托管的。
應用程序的前端調用遠程路由/控制器服務。路由/控制器服務知道組成應用程序的微服務的位置,并根據作為調用代碼一部分的某種標識符將調用轉發到適當的服務。微服務處理調用,并將結果發回給路由器/控制器作進一步處理——或者如果某個調用完成,則將響應發回給調用客戶端。
圖1. 面向微服務的體系結構的基本模式
將應用程序分成托管在遠程位置的功能這個想法始于遠程過程調用(RPC)。MOA通過添加一組常規需求來增強RPC模式。在MOA下,每個微服務:
- 支持單個關注點
- 是離散的
- 承載自己的數據
- 可以傳輸
- 是短暫的
以下是這每一項要求的含義:
支持單個關注點
微服務應該將其行為限制在單個關注點上,比如登錄服務、訂購服務、購買、處理信用卡交易的服務、支持客戶配置文件的服務、執行稅收計算的服務或日志記錄服務。
一個微服務可以使用另一個微服務,比如采購服務可以使用稅收計算服務來確定訂單的總金額。然而,不應該將兩個服務組合到一個代碼庫或單個部署單元中。
是離散的
微服務應該是離散的,因為它應該被限制在單個部署單元中,并在網絡上有清晰的邊界。該部署單元可能是Linux容器,也可能是代碼工件,比如Java .jar文件、.NET DLL或Rust二進制文件。以嵌入式系統為例,部署單元可能是一個實際的硬件。
微服務的內部組件應該是私有的,公眾無法訪問。然而,公共訪問應該由定義良好的API提供。
承載自己的數據
微服務承載自己的數據,除了通過API外,不與另一微服務共享數據。通常,微服務會有自己的數據庫或數據庫中隔離良好的表。雖然微服務之間可能出現數據冗余,但這種情形是可以接受的,也是微服務維護自己的操作狀態和邊界所必需的。
可以傳輸
微服務必須能夠在任何時候傳輸到任何托管環境。當微服務在一臺發生故障(比如斷電)的機器上運行,又必須重新部署到另一臺正常運行的機器上時,可傳輸性非常重要。
是短暫的
微服務必須能夠按需創建或銷毀。在微服務執行高強度計算、只需要滿足暫時需求的情況下,這一點尤為重要。比如說,微服務對特定的視頻文件執行特效處理。
面向嵌入式設備的MOA有何特別之處?
與為數據中心應用程序編寫MOA相比,為嵌入式環境實施MOA需要不同的方法。
首先,大多數數據中心使用Linux操作系統來驅動機器。Linux是一個功能齊全的操作系統,占用大量的內存和磁盤空間。即使是Alpine之類精簡版的Linux發行版(只有一些基本功能),這個操作系統也占用5MB的存儲空間。
許多嵌入式芯片(比如EPS32)搭載大約520KB的內部內存,其中一些容量專用于非易失性存儲。使用特殊配置時,一些芯片可能擁有高達4MB的內存和2MB到16MB的閃存。
不過,當嵌入式設備的存儲量有限(小于4MB)時,Linux無法工作。相反,嵌入式設備通常使用某種版本的實時操作系統(RTOS)。ESP32芯片組上使用的FreeRTOS操作系統只需要5 KB到10KB的代碼存儲,內存使用低至300 KB。正如您所見,與數據中心中運行的機器相比,嵌入式設備的系統需求非常小。
此外,雖然Linux支持容器,允許多個微服務在虛擬機集群中運行,但在嵌入式系統中,容器支持更多的是一種例外,而不是常態。通常,微服務將在專用的嵌入式微處理器上運行。微服務和運行微服務的硬件之間的一對一關系影響了部署和升級微服務的方式。
這不是使用Kubernetes之類的容器管理框架來重新部署容器的問題。相反,要進行升級,需要直接連接到嵌入式處理器,并且在許多情況下需要停用作為升級目標的設備。
比如說,升級運行汽車制動系統的微服務需要汽車沒有在路上行駛、處于靜止狀態。
簡而言之,為嵌入式系統部署和升級微服務的過程高度依賴系統硬件的物理狀態,但是還有另一個重要的限制因素:數據交換。
嵌入式設備之間的數據交換最好使用二進制數據格式來實施。嵌入式處理器中的空間和帶寬容量有限,因此基于文本的格式(比如XML和JSON)不能很好地工作。
相反,像協議緩沖區這樣的二進制格式或自定義二進制格式更適合MOA場景中的通信,在這種場景中,體系結構中的每個微服務都托管在嵌入式處理器上。
然而,本身在特定設備(比如汽車)內運行的嵌入式處理器和外部設備(比如手機)之間進行數據交換需要特別考慮。大多數嵌入式處理器在小型迷你板上搭載其他芯片,如圖2所示。
圖2. ESP32迷你板支持藍牙和Wi-Fi通信
這些迷你板內置藍牙和Wi-Fi功能。嵌入式芯片組可以使用這些功能與板外設備進行通信。在嵌入式芯片組根據已知格式與已知外部設備通信的情況下,使用二進制格式進行通信仍然是切實可行的。
在某些情況下,比如使用HTTP與遠程Web API通信時,較笨拙的基于文本的數據格式是規定的數據交換方式。考慮到芯片在存儲和內存方面的限制,讓每個嵌入式芯片組參與基于文本的通信可能是個問題。
另一種方法是使用專用代理芯片組與外部設備進行通信,該芯片組支持HTTP,并擁有增強的存儲和內存功能。專用代理負責管理來自其他板載嵌入式處理器的外部目標的通信。(參見圖3。)
圖3. 外部目標的專用代理使嵌入式芯片組能夠有效地通信
服務路由是另一個需要考慮的問題。正如數據中心中運行的MOA需要API網關將流量路由到指定的微服務一樣,嵌入式環境中運行的MOA也需要這樣的路由器/控制器機制。在一輛汽車中,路由器/控制器是在汽車控制器局域網(CAN)上運行的電子控制單元(ECU)。(參見圖4。)
圖4. 汽車中的CAN使用電子控制單元(ECU)來協調嵌入式設備上運行的微服務之間的數據交換
ECU可以感知汽車內運行的所有組件,并據此制定路由路線。此外,ECU還可以是維護全局狀態的控制點。
許多傳統的分布式應用程序可以在不需要應用程序中的每個微服務立即了解應用程序整體狀態的情況下運行。然而,了解系統的整體狀態對于在嵌入式系統中運行的微服務非常重要。
比如說,當自動駕駛汽車中的傳感器看到道路上的障礙物時,制動系統需要知道車輛處于危險的全局狀態,以便做出相應的反應,因此需要普遍感知全局狀態。
飛行控制系統(FCS)和樓宇管理系統(BMS)也有維護和報告全局狀態的機制。在FCS中,控制機制名為飛行管理系統或飛行管理計算機。
在BMS中,該組件名為樓宇自動化控制器或樓宇自動化系統控制器。樓宇自動化控制器報告樓宇中所有子系統的狀態,比如暖通空調、照明、安全、電梯、電氣系統和消防安全設備。
需要理解的重要一點是,任何嵌入式系統都需要一種路由機制來協調組成系統的各種設備之間的流量和數據交換。
把它們組合起來
從智能家居、自動駕駛汽車到機器人運行的工廠,物聯網和智能設備呈爆炸式增長,為精通面向微服務體系結構的軟件開發人員提供了處理嵌入式系統的更多機會。
將面向微服務的體系結構運用于嵌入式系統需要一些新知識,還需要與用于創建在數據中心虛擬化環境中運行的業務應用程序的平常做法略有不同的軟件開發方法。但考慮到面臨的機會,有望獲得重大的投資回報,值得我們應對這一挑戰。
原文標題:How to Apply Microservice Architecture to Embedded Systems,作者:Bob Reselman