當前位置:
首頁 > 最新 > 詳細描述微服務架構模式

詳細描述微服務架構模式

文章導讀

本文僅代表作者的個人觀點;

本文的內容僅限於技術探討,不能作為指導生產環境的素材;

本文素材是紅帽公司產品技術和手冊;

本文分為系列文章,將會有多篇,初步預計將會有26篇。

微服務是小型,獨立,鬆散耦合和可獨立部署的服務。它們是分散的,可以用不同的編程語言開發,在自己的進程中運行,並使用輕量級機制進行通信。

微服務以業務功能或域為模型。這些域可以進一步分為域和子域,稱為有界上下文。

微服務使用進程間通信,同步或非同步進行交互。

API網關模式為所有客戶端提供單一入口點,並簡化了服務發現。

斷路器和隔板模式在調用相關服務的微服務中提供容錯。

日誌聚合將來自所有微服務的日誌存儲在中央位置。 OpenShift使用EFK堆棧進行日誌聚合。

基於令牌的身份驗證技術(如單點登錄,分散式會話,客戶端令牌和帶有API網關的客戶端令牌)有助於保護微服務。

一、同步和非同步進程間通信

雖然微服務通常是單獨部署的,但大多數企業級微服務架構要求服務彼此交互以及與其他外部服務交互。 使用進程間通信(IPC)機制實現該通信。 根據應用程序的要求,微服務之間的通信可以是同步的或非同步的。

同步通信

同步通信基於請求和響應模型。 在此模型中,客戶端等待服務的及時響應。 一個常見的示例是通過HTTP與REST服務進行通信。

在該圖中,乘客正在使用智能手機客戶端購買新的火車票。 電話客戶端向旅行管理服務發送POST請求。 旅行管理服務向乘客管理服務發送GET請求。 乘客管理服務向狀態200 OK發送響應,返回到行程管理,其返回成功狀態201 CREATED。 在此示例中,兩個客戶端都在等待響應。

同步IPC - 優點和缺點

優點

易於編程和測試

提供更好的實時響應

使用標準防火牆埠

無需中間代理或其他集成軟體

缺點

僅支持請求和響應樣式交互

客戶和服務都必須在整個交換期間可用

客戶端必須知道服務的URL(位置)或使用服務發現機制來定位服務實例

非同步消息通信

微服務可以使用基於非同步消息的通信(例如AMQP或MQTT協議)進行通信。 微服務可以使用其他基於消息的模式,如點對點、發布和訂閱、請求和回復、或請求和通知。非同步通信是非阻塞的,因此客戶端能夠繼續發出無需等待接收響應的請求。

在上圖中,三個服務:旅行管理、乘客管理和駕駛員管理,使用單個發布 - 訂閱信道從調度員接收消息。 旅行管理服務使用另一個發布 - 訂閱頻道向調度員發送消息。 在該示例中,當提交新旅行時,調度員服務不直接回復旅行管理服務。 相反,它進行一些內部處理,然後,一旦準備就緒,使用不同的渠道來回復旅行管理服務,以及通知乘客和駕駛員管理服務。 這種非同步方法允許旅行管理服務繼續處理用戶對更多新旅行的請求,而無需等待調度員的處理和後續響應。

非同步通信 - 優點和缺點

優點

將客戶端與服務分離:客戶端不知道服務實例,不需要發現機制。

消息緩衝:消息代理在消費者緩慢或不可用時將消息排入消息緩衝區。

靈活的客戶端 - 服務交互:客戶端和服務之間的通信非常靈活。客戶端無需接收消息。消息支持各種樣式以確保消息傳遞。

缺點

額外的操作複雜性:消息組件還有其他配置。消息代理組件必須具有高可用性以確保系統可靠性。

實現基於請求和響應的交互的複雜性:每個請求消息必須包含應答信道和相關標識符。該服務將響應和相關標識符寫入回復通道。客戶端使用相關標識符識別消息。

二、了解服務發現

單個應用程序中的服務:

1.通過使用過程調用或語言級方法相互調用。

2. 使用EJB / CDI甚至JNDI來查找類路徑上的資源。

在傳統的分散式系統部署中,服務必須使用HTTP / REST或遠程過程調用(RPC)機制相互調用,並且服務在已知的固定位置(主機和埠)上運行。

基於微服務的應用程序通常在虛擬化或容器化的雲環境中運行。 網路位置會動態分配給服務實例,並且可能會因故障,自動擴展和升級而發生變化。 這些頻繁的變化使服務發現具有挑戰.

微服務的客戶端必須能夠通過不斷變化的網路位置發現這些服務實例以進行API調用。 這些客戶端需要一個精心設計的機制來成功發現服務。 有兩種主要的服務發現模式:客戶端發現和伺服器端發現。

客戶端服務發現模式

使用客戶端服務發現模式時,客戶端將查詢服務註冊表資料庫中的可用服務實例。 然後,客戶端使用負載平衡演算法選擇一個可用的服務實例。 選擇服務實例後,客戶端發出請求。 服務啟動時,它會在服務註冊表中註冊其位置。 當服務實例終止時,將從服務註冊表中刪除其服務註冊。 服務註冊表由心跳機制定期更新。

伺服器端服務發現模式

使用伺服器端服務發現模式時,客戶端通過負載均衡器向服務發出請求。 負載均衡器查詢註冊表,然後將每個請求路由到可用的服務實例。 與伺服器端服務發現類似,客戶端仍必須在註冊表中註冊自己,註冊表負責監視其健康狀況和準備情況,並刪除任何不可用的客戶端。

在Kubernetes和OpenShift中查看服務發現

OpenShift提供自己的服務發現機制,利用動態DNS正確路由請求。 在OpenShift中,服務在pod中運行,pods相當於容器的虛擬機實例。 可以將服務放置在一組pod上,這些pod可以在相同或不同的物理主機上運行。 服務是具有IP地址和埠的可路由對象,該埠充當外部通信的服務端點。 創建後,使用選擇器標籤將服務映射到pod或pod組。 然後,唯一的名稱與DNS解析的每個服務相關聯。 在較高級別,服務現在可以充當組中所有pod的負載均衡器。

容器可以使用環境變數來注入其他服務端點的值。 Kubernetes可以創建可在所有pod中訪問的環境變數。 例如,服務redis-master(公開TCP埠6379並具有分配的集群IP地址10.0.0.11)會生成以下環境變數:

REDIS_MASTER_SERVICE_HOST=10.0.0.11REDIS_MASTER_SERVICE_PORT=6379REDIS_MASTER_PORT=tcp://10.0.0.11:6379REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379REDIS_MASTER_PORT_6379_TCP_PROTO=tcpREDIS_MASTER_PORT_6379_TCP_PORT=6379REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11

集群級DNS內置於Kubernetes中。 群集DNS指向群集IP。 群集IP是在創建服務對象時分配給服務的虛擬IP。 群集IP是固定IP,因此DNS緩存沒有問題。

內部DNS伺服器為每個服務創建一組DNS記錄。 DNS伺服器使用的命名系統是稱為命名空間的分層和邏輯樹。 在同一名稱空間內,使用其名稱解析服務。 其他命名空間中的Pod可以通過將命名空間添加到DNS路徑來訪問服務,如以下示例所示:

Kubernetes / OCP服務類型

Kubernetes ServiceTypes指定服務的類型。 默認類型是ClusterIP。

ClusterIP:在集群內部IP上公開服務。 該服務只能從群集中訪問。

NodePort:在靜態埠(NodePort)上公開每個Node的IP上的服務。 可以通過每個節點上的外部NodeIP:NodePort地址訪問該服務。

LoadBalancer:使用雲提供商的負載均衡器在外部公開服務。

路由:以主機名公開服務,以便外部客戶端可以按名稱訪問它。

三、描述API網關模式

在開發微服務時解決服務發現問題的另一種方法是使用API網關模式。基於微服務的應用程序的客戶面臨許多挑戰,包括:

微服務提供細粒度的API。基於微服務的應用程序的客戶端需要與不同的服務進行交互。

不同客戶需要不同的數據。例如,產品詳細信息頁面的桌面瀏覽器版本通常比移動版本更精細。

不同類型的客戶端的網路性能不同。例如,移動和LAN客戶端通常受到不同網路性能的影響。

服務實例的數量及其位置(主機名和埠號)動態更改。

將上下文劃分為服務可以隨著時間的推移而改變,並且應該從客戶端隱藏。

服務可能使用多種協議,其中一些協議(如AMQP和二進位RPC(Thrift))可能不適合Web。

API網關模式通過提供中間服務來解決所有這些問題,該中間服務充當後端微服務和以UI為中心的客戶端(例如Web應用程序或移動應用程序)之間的傳遞層。

使用API網關

API網關是一種服務,是一個或多個微服務的主要入口點。 網關通過將請求代理到預期的微服務來處理請求。 API網關負責請求路由,組合,協議轉換,安全性,緩存和分析。

移動客戶端不使用網關直接與多個微服務通信

移動客戶端通過API網關與多個微服務進行通信

使用API網關的優點

減少客戶端與服務的耦合:將客戶端與應用程序結構隔離開來

簡化的服務發現:將客戶端與服務實例位置隔離

特定於客戶端的API:為每種類型的客戶端提供最佳API,簡化客戶端開發

使用API網關的缺點

複雜性增加:表示必須開發,部署和管理的另一個高可用性組件(API網關)

響應時間增加:通過API網關添加另一個網路躍點

潛在的開發瓶頸:每當需要暴露新的微服務或API時都需要更新

四、了解容錯

使用斷路器和隔板模式為基於微服務的應用提供容錯。容錯意味著服務可以處理故障,最終用戶體驗不會受到單個服務故障的影響。在基於微服務的應用程序中,容錯是必不可少的,因為存在很多故障點。

描述斷路器模式

斷路器模式是,用於避免微服務架構中的級聯服務故障的應用設計模式。級聯故障可能由於多種原因而發生。在運行依賴於子系統的微服務應用程序中,當單個依賴關係在高容量下顯示增加的延遲時,上游系統中的用戶請求線程變得飽和,整個應用程序可能變得無響應,從而導致級聯故障。

斷路器模式,有助於確保微服務,可以優雅地處理其所依賴的服務的下游故障。 斷路器對象將函數調用包裝到依賴服務並監視調用是否成功。 當一切正常並且呼叫成功時,斷路器處於閉合狀態。 當故障次數(呼叫期間的異常或超時)達到預先配置的閾值時,斷路器跳閘。 當斷路器打開時,不會對從屬服務進行調用,但會返回回退響應。 在可配置的時間量之後,斷路器移動到半開狀態。 在半開狀態中,斷路器定期執行服務呼叫以檢查從屬服務的健康狀況。 如果服務再次健康,並且測試呼叫成功,則電路狀態切換回關閉狀態。 斷路器生命周期如下圖所示:

回顧斷路器實現

Hystrix庫實現了斷路器和隔板模式。 它是Netflix OSS套件的一部分。 Hystrix還包括Hystrix儀錶板,允許開發人員實時監控Hystrix指標。 儀錶板還提供流聚合,以使用Netflix Turbine監控伺服器群集。

斷路器模式的其他實現可在以下方式使用:

Hystrix EIP集成在Camel中

Vert.x斷路器組件

Hystrix-javanica在Spring Boot中的集成

Wildfly Swarm Microprofile實現(基於Hystrix)

描述Bulkhead Pattern

使用隔板模式來隔離彼此的依賴關係,並限制嘗試訪問每個模塊的並發線程數。將隔板應用於服務調用時,將為該調用分配一個專用線程池(信號量)。這種隔離意味著此調用僅限於使用多個線程,如果調用變得不飽和,或者相關服務性能不佳,則會影響服務其他部分的性能。

應用程序向組件發出連接請求。單個隔板控制與每個組件的連接。當發出新連接請求時,隔板會檢查與所請求組件的連接是否可用。如果要建立連接的線程可用,則會分配連接。如果線程不可用,則等待預定義的時間間隔。如果線程在此持續時間內變為可用,則將連接分配給等待請求,否則它將拒絕該呼叫並調用回退。

五、分散式跟蹤

在單一應用程序中,跟蹤單個用戶與系統的交互,可以通過隔離應用程序的單個實例並重現問題來完成。基於微服務的應用程序很複雜; 單個微服務無法提供整個應用程序的行為,性能或正確性。

分散式跟蹤是一種工具,可在請求通過多個服務時提供應用程序行為的完整信息。 分散式跟蹤工具可以為運行服務配置文件以進行報告。 這些工具在中央聚合器中收集數據以進行存儲,報告和可視化。

分散式跟蹤使用代碼注入服務,該代碼為每個外部請求分配唯一的外部請求ID或跟蹤ID。 跟蹤ID將傳遞給處理請求所涉及的所有服務,並且跟蹤ID包含在所有日誌消息中。 每個服務都會向跟蹤添加新的跨區ID。 該服務向範圍添加元數據,例如開始和停止時間戳以及業務相關數據。 跨度數據由中央聚合器收集或發送到中央聚合器以進行存儲和可視化。

OpenTracing API

OpenTracing API是一種供應商中立的開放標準,用於跟蹤。 OpenTracing以最小的工作量提供應用程序的分散式跟蹤。 它支持多種語言,例如Java,JavaScript和Go。 它在Twitter的Zipkin,Uber的Jaeger和Red Hat的Hawkular APM中實現。

六、使用聚合日誌記錄

大多數基於微服務的應用程序,由許多獨立的微服務組成。這些服務負責執行獨特的業務任務。此外,每個服務實例可以在多台機器上運行,也可以在單獨的容器中運行每個運行的服務實例都有自己的日誌。當服務在容器中運行時,日誌將寫入stdout和stderr,並且容器和日誌都是短暫的。

有效地管理和監控所有這些日誌是一項相當大的挑戰。使用日誌聚合機制將所有日誌放入中央存儲,並使用可以適當解析日誌數據的工具。為了提供最大價值,服務應該以標準化和結構化的格式編寫日誌。應用程序記錄器應該在日誌消息中添加上下文,例如日期和時間,類名或線程號。日誌應該是可索引的,可解析的,可過濾的和可搜索的。日誌編碼器可用於生成JSON日誌消息。

OpenShift平台使用稱為EFK(Elasticsearch,fluentd和Kibana)的堆棧進行日誌聚合。使用fluentd收集日誌,這是一個日誌收集器守護程序,用於監視節點上所有正在運行的pod的容器日誌。Elasticsearch用於存儲,索引和查詢日誌。Kibana是用於日誌可視化的Web UI。

七、維護微服務中的安全性

在基於微服務的應用程序中,通過一系列獨立服務維護身份和訪問管理可能是一個真正的挑戰。要求每個服務呼叫包括認證步驟並不理想。幸運的是,有許多可能的解決方案,包括:

單點登錄:一種通用的身份驗證和授權方法,允許客戶端使用一組登錄憑據來訪問多個服務。

分散式會話:一種在微服務和整個系統之間分配身份的方法。

客戶端令牌:客戶端請求令牌並使用此令牌訪問微服務。令牌由身份驗證服務簽名。微服務在不調用身份驗證服務的情況下驗證令牌。 JSON Web Token(JWT)是基於令牌的身份驗證的示例。

使用API網關的客戶端令牌:API網關緩存客戶端令牌。令牌的驗證由API網關處理。

魏新宇

"大魏分享"運營者、紅帽資深解決方案架構師

專註開源雲計算、容器及自動化運維在金融行業的推廣

擁有MBA、ITIL V3、Cobit5、C-STAR、TOGAF9.1(鑒定級)等管理認證。

擁有紅帽RHCE/RHCA、VMware VCP-DCV、VCP-DT、VCP-Network、VCP-Cloud、AIX、HPUX等技術認證。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 大魏分享 的精彩文章:

大白話說serverless:關於無服務架構

TAG:大魏分享 |