微服務

软件架构风格

微服務(英語:Microservices)是一種軟體架構風格,它是以專注於單一責任與功能的小型功能區塊 (Small Building Blocks) 為基礎,利用模組化的方式組合出複雜的大型應用程式,各功能區塊使用與語言無關 (Language Independent),而且複雜的服務背後是使用簡單 URI 來開放介面,任何服務,任何細粒都能被開放(exposed)。這個設計在 HP 的實驗室被實現,具有改變複雜軟體系統的強大力量。

2014年,Martin FowlerJames Lewis 共同提出了微服務的概念,定義了微服務是由以單一應用程式構成的小服務,自己擁有自己的行程與輕量化處理,服務依業務功能設計,以全自動的方式部署,與其他服務使用HTTP API通訊。同時服務會使用最小的規模的集中管理 (例如 Docker) 能力,服務可以用不同的程式語言與資料庫等元件實作[1]

概念

微服務的另一個對比是單體式應用程式。單體式應用表示一個應用程式內包含了所有需要的業務功能,並且使用像主從式架構(Client/Server)或是多層次架構英語Multitier architecture(N-tier)實作,雖然它也是能以分散式應用程式來實作,但是在單體式應用內,每一個業務功能是不可分割的。若要對單體式應用進行擴展則必須將整個應用程式都放到新的運算資源(如:虛擬機器) 內,但事實上應用程式中最耗費資源、需要運算資源的僅有某個業務部份(例如跑分析報表或是數學演算法分析),但因為單體式應用無法分割該部份,因此無形中會有大量的資源浪費的現象。

微服務運用了以業務功能的設計概念,應用程式在設計時就能先以業務功能或流程設計先行分割,將各個業務功能都獨立實作成一個能自主執行的個體服務,然後再利用相同的協定將所有應用程式需要的服務都組合起來,形成一個應用程式。若需要針對特定業務功能進行擴充時,只要對該業務功能的服務進行擴展就好,不需要整個應用程式都擴展,同時,由於微服務是以業務功能導向的實作,因此不會受到應用程式的干擾,微服務的管理員可以視運算資源的需要來組態微服務到不同的運算資源內,或是佈建新的運算資源並將它組態進去。

雖然使用一般的伺服器虛擬化技術就能應用於微服務的管理,但容器技術 (Container Technology) 如 Docker 會更加地適合發展微服務的運算資源管理技術。

規劃

 
微服務中每個服務都能夠有自己的資料庫。

微服務的規劃與單體式應用程式十分不同,微服務中每個服務都需要避免與其他服務有所牽連,且都要能夠自主,並在其他服務發生錯誤時不受干擾。

 
如果資料庫都是分開的,那麼新服務上線時就會遇到資料庫為空的窘境。我們並不能從另一個服務複製資料過來,因為我們無法確定該服務擁有最新的資料。 此時應該從事件儲存中心重播所有事件,如此一來就可以找回先前的所有、最新的資料。

資料庫

微服務理念中有數個資料庫的規劃方式。

  • 每個服務都各有一個資料庫,同屬性的服務可共享同個資料庫。
  • 所有服務都共享同個資料庫,但是不同表格,並且不會跨域存取。
  • 每個服務都有自己的資料庫,就算是同屬性的服務也是,資料庫並不會共享。

資料庫並不會只存放該服務的資料,而是「該服務所會用到的所有資料」。更深層一點的舉例:假設有個文章服務,而這個服務可能會需要判斷使用者的帳號⋯⋯等。那麼文章服務的資料庫就可以放入使用者的部分資料。此舉是為了避免服務之間的相依性,避免文章服務呼叫使用者服務。

資料庫的可棄性

實踐微服務有許多的做法,但其中一種做法是將資料庫作為短期的儲存空間而不是儲存長期的資料。這意味著資料庫可以在離線時被清空。因為它們可以在上線時從事件儲存中心恢復,因此也能以記憶體快取(如:Redis) 作為資料庫伺服器。但這種做法需要將每個請求當作事件來進行廣播。如此一來就可以從事件儲存中心重播所有的事件來找回所有的資料。

溝通與事件廣播

 
NSQ 是一個訊息佇列系統、平台。在微服務中所扮演的角色是將訊息、資料傳遞到其他服務。 此舉是非同步執行,所以不需要等到其他服務接收到訊息就能夠執行下一步。這種方式能夠避免服務之間有所牽連、呼叫。

微服務中最重要的就是每個服務的獨立與自主,因此服務與服務之間也不應該有所溝通。倘若真有溝通,也應採用非同步溝通的方式來避免緊密的相依性問題。要達到此目的,則可用下列兩種方式:

事件儲存中心(Event Store)

這可以讓你在服務叢集中廣播事件,並且在每個服務中監聽這些事件並作處理,這使得服務之間不需有緊密的相依性,而這些發生的事件都會被儲存在事件儲存中心裡。這意味著當微服務重新上線、部署時可以重播(Replay)所有的事件。這也造就了微服務的資料庫隨時都可以被刪除、摧毀,且不需要從其他服務中取得資料。

服務探索

單個微服務在上線的時候,會向服務探索中心(如:Consul)註冊自己的 IP 位置、服務內容,如此一來就不需要向每個微服務表明自己的 IP 位置,也就不用替每個微服務單獨設定。當服務需要呼叫另一個服務的時候,會去詢問服務探索中心該服務的 IP 位置為何,得到位置後即可直接向目標服務呼叫。

這麼做的用意是可以統一集中所有服務的位置,就不會分散於每個微服務中,且服務探索中心可以每隔一段時間就向微服務進行健康檢查(如透過:TCP 呼叫、HTTP 呼叫、Ping),倘若該服務在時間內沒有回應,則將其從服務中心移除,避免其他微服務對一個無回應的服務進行呼叫。

內容

一個微服務架構的應用程式有下列特性:

  • 每個服務都容易被取代。
  • 服務是以能力來組織的,例如使用者介面、前端、推薦系統、帳單或是物流等。
  • 由於功能被拆成多個服務,因此可以由不同的程式語言、資料庫實作。
  • 架構是對稱而非分層(即生產者與消費者的關係)。

一個微服務架構:

  • 適用於具持續交付(Continuous Delivery)的軟體開發流程。
  • 服務導向架構(Service-Oriented Architecture)不同,後者是整合各種業務的應用程式,但微服務只屬於一個應用程式。

技術

微服務可以用不同的程式語言實現,也可以使用不同的基礎設施。[2]因此,最重要的技術選擇是微服務之間的通訊方式(同步、非同步、UI整合)以及用於通訊的協定(RESTful HTTP、訊息、GraphQL……)。在傳統系統中,大多數技術選擇,如程式語言,都會影響整個系統。因此,選擇技術的方法是完全不同的。[3]

Eclipse基金會已經發布了開發微服務的規範——Eclipse MicroProfile。[4]

Service mesh

在服務網格中,每個服務實例都與一個反向代理伺服器實例(稱為服務代理、 sidecar代理或sidecar)配對。服務實例和 sidecar 代理共享一個容器,容器由一個容器編排工具(如KubernetesNomadDocker SwarmDC/OS)管理。 服務代理負責與其他服務實例的通訊,並支援服務(實例)發現、負載平衡、身分驗證和授權、安全通訊等功能。

在服務網格中,服務實例及其sidecar代理被稱為構成資料平面,其中不僅包括資料管理,還包括請求處理和回應。服務網格還包括一個用於管理服務之間互動的控制平面,這些互動由它們的sidecar代理協調。服務網格架構有幾個選項: IstioLinkerdConsul和其他許多服務網格景觀。服務網格管理平面Meshery頁面存檔備份,存於網際網路檔案館)提供跨服務網格部署的生命周期、組態和效能管理。

平台比較

實現微服務體系結構非常困難。任何微服務體系結構都需要解決許多問題(見下表)。Netflix開發了一個微服務架構來支持他們的內部應用程式,然後開放了[5]該框架的許多部分。其中許多工具已經通過Spring框架得到推廣——它們已經在Spring Cloud專案的保護傘下重新實現為基於Spring的工具。[6] 下表顯示了Kubernetes生態系統中的實現功能與Spring Cloud世界中的等效功能的比較。[7] Spring Cloud生態系統值得注意的一點是,它們都是基於Java的技術,而Kubernetes是一個多語言執行時平台。

微服務 Spring Cloud與Netflix OSS Kubernetes
組態管理:微服務應用程式的組態需要從代碼中進行外部化,並可以通過簡單的服務呼叫進行檢索。 Spring Config Server、Netflix Archaius都支援基於Git儲存庫的組態位置。Archaius支援組態資料類型。 Kubernetes ConfigMaps通過服務公開儲存在etcd中的組態。 Kubernetes Secrets支援基於服務的安全部署和敏感組態資訊(例如密碼,憑證等)的使用。
服務發現:維護微服務域中可用於工作的服務實例列表。 Spring Cloud Eureka允許客戶端向其註冊,與註冊的客戶端保持心跳,並將服務名稱對映到按服務名稱尋找服務的客戶端的主機名。 Kubernetes Services提供叢集內部可用的服務實例的部署時註冊。Ingress是一種機制,通過這種機制,服務可以向叢集之外的客戶端公開。
負載平衡:擴充分散式系統的關鍵是能夠執行一個組件的多個實例。然後要通過負載均衡器將負載分配到這些實例上。 Spring Cloud Ribbon為服務客戶端提供跨服務實例負載平衡的能力。 Kubernetes Service提供了跨服務實例對服務進行負載平衡的能力。這與Ribbon提供的功能不同。
API閘道器:微服務提供的API的粒度通常與服務客戶端需要的粒度不同。API閘道器實現表層,並提供其他服務,如代理、協定轉換和其他管理功能。 Spring Cloud Zuul提供基於組態的API表層 Kubernetes Service和Ingress resources、Istio、Ambassador是提供南北(進出資料中心)和東西(跨資料中心或雲或地區的通訊)API閘道器功能的解決方案。
安全問題:許多安全問題推給API閘道器來實現。對於分散式微服務應用程式,不重新造安全方面的輪子,允許在所有服務共享的組件中進行策略定義和實現是有意義的。 Spring Cloud Security通過Spring Cloud Zuul解決了許多安全問題 Kubernetes生態系統提供了像Istio這樣的服務網格,該網格能夠通過其API閘道器機制提供安全性。
集中化紀錄檔記錄:擁有一個集中化的紀錄檔收集和分析基礎設施來管理大量的服務非常重要——其中許多服務是以分散式方式執行的。 ELK技術棧(Elasticsearch、LogStash、Kibana EFK技術棧(ElasticsearchFluentdKibana
集中的度量:一個可以監控單個服務和整個系統的健康和效能的集中區域對於正確的操作是必不可少的。 Spring Spectator & Atlas Heapster, Prometheus, & Grafana
分散式跟蹤:每個行程的紀錄檔記錄和度量監視都有其存在的地方,但它們都不能重構事務在跨分散式系統傳播時所採用的複雜路徑。分散式跟蹤是微服務平台必不可少的工具。 Spring Cloud Sleuth Hawkular, Jaeger
彈性和容錯性:分散式系統必須能夠圍繞故障進行自動路由,並且能夠將請求路由到提供最佳回應的服務實例。 Spring Hystrix, Turbine, & Ribbon Health check, service meshes (example: Istio)[8]
自動伸縮和自我修復:分散式系統通過水平伸縮回應更高的負載: 平台必須檢測並自動回應這些條件。此外,系統需要檢測故障,並嘗試自動重新啟動,無需操作員輸入。 - 健康檢查、自我修復和自動縮放
打包、部署和排程: 大規模系統需要健壯的包管理和部署系統來管理捲動部署或藍綠色部署,並在必要時進行轉返。排程程式幫助確定可以根據當前條件將一組新服務部署到哪個特定的執行節點。 Spring Boot, Apache Maven. Spring Cloud系統沒有真正的排程程式。 Docker, Rkt, Kubernetes Scheduler & Deployment, Helm[9]
作業管理:控制無人值守的後台程式執行。 Spring Batch Kubernetes Jobs與Scheduled Jobs
單例應用程式:限制特定服務作為該服務在整個系統中的唯一實例執行。 Spring Cloud Cluster Kubernetes Pods

相關程式語言

微服務採用者

平台實作

參考

  1. ^ Microservices: A definition of this new architectural term. [2016-03-18]. (原始內容存檔於2018-02-14). 
  2. ^ Microservices Testing Strategies, Types & Tools: A Complete Guide. Simform. [2021-06-29]. (原始內容存檔於2021-06-29). 
  3. ^ Wolff, Eberhard. Microservices - A Practical Guide. 2018-04-15 [2021-10-01]. ISBN 978-1717075901. (原始內容存檔於2021-05-01). 
  4. ^ Swart, Stephanie. Eclipse MicroProfile. projects.eclipse.org. 14 December 2016 [2020-07-20]. (原始內容存檔於2022-01-19). 
  5. ^ Netflix OSS, Git Hub, [2020-07-20], (原始內容存檔於2021-05-01) 
  6. ^ Cloud, Spring, [2020-07-20], (原始內容存檔於2022-06-22) 
  7. ^ Spring Cloud for Microservices Compared to Kubernetes, Developers (Red hat), 2016-12-09 [2020-07-20], (原始內容存檔於2021-05-01) 
  8. ^ Managing microservices with the Istio service mesh, Kubernetes, May 2017 [2020-07-20], (原始內容存檔於2021-05-01) 
  9. ^ The Kubernetes Package Manager, Helm, [2020-07-20], (原始內容存檔於2021-05-01) 
  10. ^ Jolie. [2022-06-26]. (原始內容存檔於2022-06-09). 
  11. ^ AnyPresence Launches a New API Platform for Mobile and IoT Developers. [2016-03-18]. (原始內容存檔於2021-05-11). 
  12. ^ How Enterprise PaaS can add Critical Value to Microservices. [2016-03-18]. (原始內容存檔於2015-05-08). 
  13. ^ Developing Microservices for PaaS with Spring and Cloud Foundry. [2016-03-18]. (原始內容存檔於2021-05-01). 
  14. ^ Microservices (PDF). [永久失效連結]
  15. ^ Microservices. [2016-03-18]. (原始內容存檔於2021-04-13). 
  16. ^ Microservices. [2016-03-18]. (原始內容存檔於2016-03-26). 
  17. ^ Products > Platform. 1060 Research Ltd. [12 October 2015]. (原始內容存檔於2015-08-12). 
  18. ^ Wilma documentation. [2016-03-18]. (原始內容存檔於2020-09-20). 
  19. ^ Wilma source code. [2016-03-18]. (原始內容存檔於2022-03-27). 
  20. ^ Vertx. [2022-06-26]. (原始內容存檔於2021-12-24). 
  21. ^ Baratine. [2021-10-01]. (原始內容存檔於2015-11-09). 
  22. ^ KumuluzEE. [2022-06-26]. (原始內容存檔於2022-03-31).