微服務是一種軟體架構風格，它是以專注於單一責任與功能的小型功能區塊 Small Building Blocks 為基礎，利用模組化的方式組合出複雜的大型應用程式，各功能區塊使用與語言無關 Language Independent），而且複雜的服務背後是使用簡單 URI 來開放介面，任何服務，任何細粒都能被開放（exposed）。這個設計在 HP 的實驗室被實現，具有改變複雜軟體系統的強大力量。 2014 年，Martin Fowler 與 James Lewis 共同提出了微服務的概念，定義了微服務是由以單一應用程式構成的小服務，自己擁有自己的程序與輕量化處理，服務依業務功能設計，以全自動的方式部署，與其他服務使用 HTTP API 通訊。同時服務會使用最小的規模的集中管理 例如 Docker 能力，服務可以用不同的程式語言與資料庫等元件實作。 概念 微服務的另一個對比是單體式應用程式。單體式應用表示一個應用程式內包含了所有需要的業務功能，並且使用像主從式架構（ClientServer）或是（Ntier）實作，雖然它也是能以分散式應用程式來實作，但是在單體式應用內，每一個業務功能是不可分割的。若要對單體式應用進行擴充套件則必須將整個應用程式都放到新的運算資源（如：虛擬機器） 內，但事實上應用程式中最耗費資源、需要運算資源的僅有某個業務部份（例如跑分析報表或是數學演演算法分析），但因為單體式應用無法分割該部份，因此無形中會有大量的資源浪費的現象。 微服務運用了以業務功能的設計概念，應用程式在設計時就能先以業務功能或流程設計先行分割，將各個業務功能都獨立實作成一個能自主執行的個體服務，然後再利用相同的協定將所有應用程式需要的服務都組合起來，形成一個應用程式。若需要針對特定業務功能進行擴充時，只要對該業務功能的服務進行擴充套件就好，不需要整個應用程式都擴充套件，同時，由於微服務是以業務功能導向的實作，因此不會受到應用程式的幹擾，微服務的管理員可以視運算資源的需要來配置微服務到不同的運算資源內，或是佈建新的運算資源並將它配置進去。 雖然使用一般的伺服器虛擬化技術就能應用於微服務的管理，但容器技術 Container Technology 如 Docker 會更加地適合發展微服務的運算資源管理技術。 規劃 微服務的規劃與單體式應用程式十分不同，微服務中每個服務都需要避免與其他服務有所牽連，且都要能夠自主，並在其他服務發生錯誤時不受幹擾。 資料庫 微服務理念中有數個資料庫的規劃方式。 每個服務都各有一個資料庫，同屬性的服務可共享同個資料庫。 所有服務都共享同個資料庫，但是不同表格，並且不會跨域存取。 每個服務都有自己的資料庫，就算是同屬性的服務也是，資料庫並不會共享。 資料庫並不會只存放該服務的資料，而是「該服務所會用到的所有資料」。更深層一點的舉例：假設有個文章服務，而這個服務可能會需要判斷使用者的帳號等。那麼文章服務的資料庫就可以放入使用者的部分資料。此舉是為了避免服務之間的相依性，避免文章服務呼叫使用者服務。 資料庫的可棄性 實踐微服務有許多的做法，但其中一種做法是將資料庫作為短期的儲存空間而不是儲存長期的資料。這意味著資料庫可以在離線時被清空。因為它們可以在上線時從事件儲存中心恢復，因此也能以記憶體快取（如：Redis） 作為資料庫伺服器。但這種做法需要將每個請求當作事件來進行廣播。如此一來就可以從事件儲存中心重播所有的事件來找回所有的資料。 溝通與事件廣播 微服務中最重要的就是每個服務的獨立與自主，因此服務與服務之間也不應該有所溝通。倘若真有溝通，也應採用非同步溝通的方式來避免緊密的相依性問題。要達到此目的，則可用下列兩種方式： 事件儲存中心（Event Store） 這可以讓你在服務叢集中廣播事件，並且在每個服務中監聽這些事件並作處理，這使得服務之間不需有緊密的相依性，而這些發生的事件都會被儲存在事件儲存中心裡。這意味著當微服務重新上線、部署時可以重播（Replay）所有的事件。這也造就了微服務的資料庫隨時都可以被刪除、摧毀，且不需要從其他服務中取得資料。 服務探索 單個微服務在上線的時候，會向服務探索中心（如：Consul）註冊自己的 IP 位置、服務內容，如此一來就不需要向每個微服務表明自己的 IP 位置，也就不用替每個微服務單獨設定。當服務需要呼叫另一個服務的時候，會去詢問服務探索中心該服務的 IP 位置為何，得到位置後即可直接向目標服務呼叫。 這麼做的用意是可以統一集中所有服務的位置，就不會分散於每個微服務中，且服務探索中心可以每隔一段時間就向微服務進行健康檢查（如透過：TCP 呼叫、HTTP 呼叫、Ping），倘若該服務在時間內沒有回應，則將其從服務中心移除，避免其他微服務對一個無回應的服務進行呼叫。 內容 一個微服務架構的應用程式有下列特性： 每個服務都容易被取代。 服務是以能力來組織的，例如使用者介面、前端、推薦系統、帳單或是物流等。 由於功能被拆成多個服務，因此可以由不同的程式語言、資料庫實作。 架構是對稱而非分層（即生產者與消費者的關係）。 一個微服務架構： 適用於具持續交付（Continuous Delivery）的軟體開發流程。 與服務導向架構（ServiceOriented Architecture）不同，後者是整合各種業務的應用程式，但微服務只屬於一個應用程式。 技術 微服務可以用不同的程式語言實現，也可以使用不同的基礎設施。因此，最重要的技術選擇是微服務之間的通訊方式（同步、非同步、UI 整合）以及用於通訊的協議（RESTful HTTP、訊息、GraphQL）。在傳統系統中，大多數技術選擇，如程式語言，都會影響整個系統。因此，選擇技術的方法是完全不同的。 Eclipse 基金會已經發布了開發微服務的規範 Eclipse MicroProfile。 Service mesh 在服務網格中，每個服務例項都與一個反向代理伺服器例項（稱為服務代理、 sidecar 代理或 sidecar）配對。服務例項和 sidecar 代理共享一個容器，容器由一個容器編排工具（如 Kubernetes、Nomad、Docker Swarm、DCOS）管理。 服務代理負責與其他服務例項的通訊，並支援服務（例項）發現、負載平衡、身份驗證和授權、安全通訊等功能。 在服務網格中，服務例項及其 sidecar 代理被稱為構成資料平面，其中不僅包括資料管理，還包括請求處理和響應。服務網格還包括一個用於管理服務之間互動的控制平面，這些互動由它們的 sidecar 代理協調。服務網格架構有幾個選項 Istio、Linkerd、Consul 和其他許多服務網格景觀。服務網格管理平面 Meshery 提供跨服務網格部署的生命週期、配置和效能管理。 平臺比較 實現微服務體系結構非常困難。任何微服務體系結構都需要解決許多問題（見下表）。Netflix 開發了一個微服務框架來支援他們的內部應用程式，然後開放了該框架的許多部分。其中許多工具已經透過 Spring 框架得到推廣 它們已經在 Spring Cloud 專案的保護傘下重新實現為基於 Spring 的工具。 下表顯示了 Kubernetes 生態系統中的實現功能與 Spring Cloud 世界中的等效功能的比較。 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 技術棧（Elasticsearch、Fluentd、Kibana） 集中的度量：一個可以監控單個服務和整個系統的健康和效能的集中區域對於正確的操作是必不可少的。 Spring Spectator Atlas Heapster Prometheus Grafana 分散式跟蹤：每個程序的日誌記錄和度量監視都有其存在的地方，但它們都不能重構事務在跨分散式系統傳播時所採用的複雜路徑。分散式跟蹤是微服務平臺必不可少的工具。 Spring Cloud Sleuth Hawkular Jaeger 彈性和容錯性：分散式系統必須能夠圍繞故障進行自動路由，並且能夠將請求路由到提供最佳響應的服務例項。 Spring Hystrix Turbine Ribbon Health check service meshes example Istio 自動伸縮和自我修復：分散式系統透過水平伸縮響應更高的負載：平臺必須檢測並自動響應這些條件。此外，系統需要檢測故障，並嘗試自動重啟，無需操作員輸入。 健康檢查、自我修復和自動縮放 打包、部署和排程：大規模系統需要健壯的包管理和部署系統來管理滾動部署或藍綠色部署，並在必要時進行回滾。排程程式幫助確定可以根據當前條件將一組新服務部署到哪個特定的執行節點。 Spring Boot Apache Maven Spring Cloud 系統沒有真正的排程程式。 Docker Rkt Kubernetes Scheduler Deployment Helm 作業管理：控制無人值守的後臺程式執行。 Spring Batch Kubernetes Jobs 與 Scheduled Jobs 單例應用程式：限制特定服務作為該服務在整個系統中的唯一例項執行。 Spring Cloud Cluster Kubernetes Pods 相關程式語言 微服務採用者 Akana Amazon AnyPresence JustAPIs Apprenda Axway 1060 Research Ltd Bluemix Cloud Foundry Google The Guardian Hailo Taxi HP Helion Development Platform Jelastic Microsoft Azure Netflix Nirmata nearForm Riot Games SoundCloud Uber Joined Node 平臺實作 Apache ServiceComb Docker Microsoft Service Fabric overview blog announcement MicroService4Net NetKernel Nirmata Seneca Microservices Framework and Protocol Spring Cloud 微服務測試工具：Wilma Vertx Baratine KumuluzEE EnduroX 參考 Category 雲端運算