剝析surging的架構思想

fanly11發表於2017-07-16

1、前言

 

前面第一篇闡述了採用基於.NET CORE微服務架構,應用surging服務端與客戶端之間進行通訊的簡單示例以及對於surging服務化框架簡單介紹。在這篇文章中,我們將剝析surging的架構思想。

surging原始碼下載

2、通訊機制

2.1 簡介

     在單體應用中,模組之間的呼叫通訊通過引用載入方法或者函式來實現,但是單體應用最終都會因為團隊壯大,專案模組的擴充套件和部署等出現難以維護的問題。隨著業務需求的快速發展變化,敏捷性、靈活性和可擴充套件性需求不斷增長,迫切需要一種更加快速高效的軟體交付方。微服務可以彌補單體應用不足,是一種更加快速高效軟體架構風格。單體應用被分解成多個更小的服務,每個服務有自己的獨立模組,單獨部署,然後共同組成一個應用程式。把範圍限定到單個獨立業務模組功能。分散式部署在各臺伺服器上。一般來說,每個微服務都是一個程式。而各服務之間的互動必須通過程式間通訊(IPC)來實現

 2.2 互動模式

互動模式有以下幾種方式:

• 請求/響應:客戶端向伺服器端發起請求,同步等待響應,等待過程可能造成執行緒阻塞。
• 通知(也就是常說的單向請求):客戶端請求傳送到服務端,服務端不返回請求響應。
• 請求/非同步響應:客戶端傳送請求到服務端,服務端非同步響應請求。客戶端不會阻塞,而且被設計成預設響應不會立刻到達。

• 釋出/ 訂閱模式:客戶端釋出通知訊息,被零個或者多個訂閱者服務消費。

• 釋出/非同步響應模式:客戶端釋出請求訊息,然後非同步或者回撥服務發回響應。

服務之間的通訊可以使用同步的請求/響應和請求/非同步響應模式,在surging框架採用的基於RPC的netty 請求/非同步響應和基於rabbitmq 的訊息通訊模式。首先來看非同步訊息通訊模式

2.1.1 非同步訊息通訊模式

Surging採用基於Rabbitmq釋出訂閱的非同步交換訊息的IPC程式通訊,客戶端通過pub釋出請求,然後服務端進行Consume,之間的通訊是非同步,客戶端不會因為等待而阻塞。

   訊息由頭部(後設資料)和訊息體構成,生產者傳送訊息到channel,消費者則通過channel接受資料,channel 則分為點對點和釋出訂閱,點對點Channel 會把訊息準確傳送到消費者,之間採用的是一對一的互動模式。而釋出/訂閱則把訊息PUB到所有從channel 訂閱訊息的消費者中,之間採用的一對多的互動模式

2.1.2 基於請求/非同步響應通訊模式

Surging採用基於netty的 (IPC)程式通訊,是基於請求/非同步響應的IPC機制,客戶端向服務端傳送請求,服務端處理請求,非同步響應,客戶端不會因為等待服務返回而阻塞其它請求。

在請求/非同步響應模式中,伺服器端非同步響應是在多處理器系統上可以並行處理或者單處理上交錯執行,這使得當某個執行緒阻塞請求的同時其它執行緒得以繼續執行。但訪問共享資源時,需要保證其執行緒安全,可以通過鎖,先進先出集合或者其它機制來處理執行緒安全的問題。

3、部署和呼叫

1.單體應用架構

當網站流量很小時,只需要將所有功能部署在一起,以減少部署節點和成本

單體架構業務流程往往在同一個程式內部完成處理,不需要進行分散式協作,它的工作原理如下:

 


圖 1-1 單體架構本地方法呼叫

 

2.垂直應用架構

當訪問量逐漸增大,單體架構壓力越來越大,將架構拆成互不相干的若干應用以提升效率,此時採用MVC、webAPI進行呼叫

 

3.分散式微服務架構

當垂直應用越來越多,應用之間互動不可避免,可以將各個獨立的業務模組,部署成獨立的微服務,逐漸形成穩定的服務中心。

而Surging 微服務採用分散式叢集部署方式,服務的消費者和提供者通常執行在不同的程式中,程式之間通訊採用RPC方式呼叫,它的工作原理如下:

                                                                         圖1-2 Surging分散式RPC呼叫

        Surging微服務採用基於netty進行通訊,資料之間的傳遞通過序列化和反序列JSON,相比於本地方法呼叫,會產生如下問題:

       1.資料序列化問題:微服務程式的通訊都需要經過序列化和反序列化,因資料結構不一致、資料型別的不支援、編碼錯誤都會造成資料轉化的失敗,從而導致呼叫失敗

       2.網路問題:常見的包括網路超時、網路閃斷、網路阻塞等, 都會導致微服務遠端呼叫失敗。

       每個微服務都獨立打包部署,讓服務之間進行程式隔離,對於大型的網際網路專案,會有成百上千的微服務,通常不會百分百獨立部署,對於同一業務的微服務會打包部署在一起,對於時延非常敏感,會合設在同一程式之內,採用本地方法呼叫。

不同的微服務合設在同一程式中,會產生以下問題:

  1. 處理較慢的微服務會阻塞其它微服務
  2. 某個微服務故障,可能導致整個程式不可用

3、總體架構

  Surging框架程式碼邏輯一共劃分了8層,各個層的設計要點:

  • 業務模組服務介面層(IModuleServices):該層是與實際業務邏輯相關的,根據服務提供方和服務消費方,設計業務模組介面。
  • 業務模組服務層(ModuleServices):該層是通過Domain和Repository實現實際業務邏輯
  • 基礎通訊平臺(CPlatform):提供基礎資料通訊對應的介面和基礎實現,如:基礎日誌,遠端呼叫服務,Event bus,負載均衡演算法,資料序列化等
  • DotNetty服務層(DotNetty):實現基於DotNetty服務的資訊的傳送和接收
  • RabbitMQ服務層(EventBusRabbitMQ):封裝基於Rabbitmq的釋出訂閱的事件匯流排
  • 代理服務層(ProxyGenerator):封裝代理服務的生成及建立呼叫。
  •  服務註冊層(Zookeeper):封裝服務地址的註冊與發現,以Zookeeper為服務註冊中心,實現ServiceRouteManagerBase抽象,通過心跳檢測的方式更新路由
  • 系統服務層(system):對於系統底層介面的封裝

4、分散式的可靠性

      Surging 微服務的執行質量,除了自身的可靠性因素之外,還受到其它因素的影響,包括網路,資料庫訪問,其它關聯的微服務的執行質量,可靠性設計,需要考慮上述綜合因素,總結如下:

     

4.1 非同步I/O 操作

  4.1.1 網路I/O

  1.同步阻塞I/o 通訊:

  即典型的請求/響應模式。  該模型最大的問題就是缺乏彈性伸縮能力,當客戶端併發訪問量增加後,服務端的執行緒個數和客戶端併發訪問數呈1:1的正比關係,執行緒數量快速膨脹後,系統的效能將急劇下降,隨著訪問量的繼續增大,系統最終崩潰。

  1. 非同步非阻塞I/O 通訊:

  Surging 是基於Netty進行非同步非阻塞I/O 通訊,即典型的請求/非同步響應模式。此模式的優點如下:

  1. 更好的吞吐量,低延遲,更省資源
  2. 不再因過快、過慢或超負載訪問導致系統崩潰

  4.1.2 磁碟I/O

  微服務對磁碟I/O的操作主要分為同步檔案操作和非同步檔案操作,

  在Surging專案中,需要從註冊中心獲取路由資訊快取到本地,通過建立代理,負載均衡演算法選擇Router,路由資訊的快取到採用的是心跳檢測的方式進行更新。

  4.1.3 資料庫操作

  一般來說檔案 I/O、網路訪問乃至於程式間同步通訊,以及本節所討論的 資料庫訪問等都較為耗時,ado.net,Entity Framework以及其它ORM框架都提供了非同步執行方法。

4.2 故障隔離

  由於大部分微服務採用同步介面呼叫,而且多個領域相關的微服務會部署在同一個程式中,很容易發生“雪崩效應”,即某個微服務提供者故障,導致呼叫該微服務的消費者、或者與故障微服務合設在同一個程式中的其它微服務發生級聯故障,最終導致系統崩潰。為了避免“雪崩效應”的發生,需要支援多種維度的依賴和故障隔離,

  4.1.1 通訊鏈路隔離

  由於網路通訊本身通常不是系統的瓶頸,因此大部分服務框架會採用多執行緒+單個通訊鏈路的方式進行通訊,原理如下所示:

      

  4.1.2 排程資源隔離

  4.1.2.1微服務之間隔離

  當多個微服務合設執行在同一個程式內部時,可以利用執行緒實現不同微服務之間的隔離。

4.3 程式級隔離

對於核心的微服務,例如商品使用者註冊、計費、訂單等,可以採用獨立部署的方式,實現高可用性。

4.3.1 容器隔離

  微服務將整個專案解耦成各個獨立的業務模組,部署成獨立的微服務,利用Docker 容器部署微服務可以升級和擴容,並且有以下優點:

  高效:使用Docker部署微服務,微服務的啟動    和銷燬速度非常快,在高壓力時,可以實現秒級彈性伸縮。

  高效能:Docker 容器的效能接近邏輯,比VM高20%

  隔離性:可以實現高密度的部署微服務,而且是基於細粒度的資源隔離機制,實現微服務隔離,保證微服務的可靠性

  可移植性:通過將執行環境和應用程式打包到一起,來解決部署的環境依賴問題,真正做到跨平臺的分發和使用。可謂是一次編寫,到處執行。

4.3.2 VM隔離

  除了Docker容器隔離,也可以使用VM對微服務進行故障隔離,相比於Docker容器,使用VM進行微服務隔離存在如下優勢:

  1.微服務的資源隔離性更好,CPU、記憶體、網路等可以實現完全的資源隔離。

  2.對於已經完成硬體虛擬化的遺留系統,可以直接使用已有的VM,而不需要在VM中重新部署Docker容器。

4.4 叢集容錯

           略

5、Cache和EventBus中介軟體

5.1 Cache 中介軟體設計  

設計目標:

  1. 將快取伺服器的部署配置與應用隔離,
  2. 實現分散式,提高資料的均勻分佈,並且能實現故障隔離
  3. 根據KEY字首的不同分配到MemoryCache 或者redis 上
  4. 統計快取的使用情況,便於分析和提高快取合理資源的分配。

設計如下:

   

  快取中介軟體內部使用一致性雜湊演算法實現分散式。設定的虛擬節點能均勻分佈。

  快取中介軟體暫時只實現Redis,MemoryCache做為快取服務。後期應該會實現CacheBase

  快取中介軟體後期會提供配置服務,方便管理快取服務配置,以及顯示一些狀態資訊

 5.2 EventBus中介軟體設計

設計目標:

  1. 基於釋出/訂閱的模式非同步傳遞訊息。
  2. 整合第三方訊息中介軟體,如:MSMQ,Rabbitmq
  3. 實現基於釋出/訂閱的非同步通知

設計如下:

          

        1.publisher: 是釋出者把訊息事件Event通過Event Bus 釋出到Topic

        2.Event bus::是事件匯流排,對於publisher 和 Subscriber 之間進行解耦,找到已經註冊的事件訂閱者,訊息事件Event傳送到topic

        3.Topic: 是訊息路由對於訂閱者以廣播的形式,讓線上的Subscriber接收訊息事件。

        4.Subscriber:是訂閱者, 收到事件匯流排發下來的訊息。即Handle方法被執行。注意引數型別必須和釋出者釋出的引數一致。

5、總結

          surging 0.0.0.1版本還有很多需要完善的地方,比如路由容錯,服務降級、熔斷,監控平臺和配置服務平臺,以及後續的第三方中介軟體的整合,這些任務都已經規劃到日程,再不久的將來會看到1.0穩定版本的釋出 ,如有興趣可以加入QQ群:542283494

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章