前面第一篇闡述了採用基於.NET CORE微服務架構,應用surging服務端與客戶端之間進行通訊的簡單示例以及對於surging服務化框架簡單介紹。在這篇文章中,咱們將剝析surging的架構思想。html
surging源碼下載git
在單體應用中,模塊之間的調用通訊經過引用加載方法或者函數來實現,可是單體應用最終都會由於團隊壯大,項目模塊的擴展和部署等出現難以維護的問題。隨着業務需求的快速發展變化,敏捷性、靈活性和可擴展性需求不斷增加,迫切須要一種更加快速高效的軟件交付方式。微服務能夠彌補單體應用不足,是一種更加快速高效軟件架構風格。單體應用被分解成多個更小的服務,每一個服務有本身的獨立模塊,單獨部署,而後共同組成一個應用程序。把範圍限定到單個獨立業務模塊功能。分佈式部署在各臺服務器上。通常來講,每一個微服務都是一個進程。而各服務之間的交互必須經過進程間通訊(IPC)來實現github
交互模式有如下幾種方式:web
• 請求/響應:客戶端向服務器端發起請求,同步等待響應,等待過程可能形成線程阻塞。
• 通知(也就是常說的單向請求):客戶端請求發送到服務端,服務端不返回請求響應。
• 請求/異步響應:客戶端發送請求到服務端,服務端異步響應請求。客戶端不會阻塞,並且被設計成默認響應不會馬上到達。redis
• 發佈/ 訂閱模式:客戶端發佈通知消息,被零個或者多個訂閱者服務消費。算法
• 發佈/異步響應模式:客戶端發佈請求消息,而後異步或者回調服務發回響應。數據庫
服務之間的通訊可使用同步的請求/響應和請求/異步響應模式,在surging框架採用的基於RPC的netty 請求/異步響應和基於rabbitmq 的消息通訊模式。首先來看異步消息通訊模式緩存
Surging採用基於Rabbitmq發佈訂閱的異步交換消息的IPC進程通訊,客戶端經過pub發佈請求,而後服務端進行Consume,之間的通訊是異步,客戶端不會由於等待而阻塞。安全
消息由頭部(元數據)和消息體構成,生產者發送消息到channel,消費者則經過channel接受數據,channel 則分爲點對點和發佈訂閱,點對點Channel 會把消息準確發送到消費者,之間採用的是一對一的交互模式。而發佈/訂閱則把消息PUB到全部從channel 訂閱消息的消費者中,之間採用的一對多的交互模式服務器
Surging採用基於netty的 (IPC)進程通訊,是基於請求/異步響應的IPC機制,客戶端向服務端發送請求,服務端處理請求,異步響應,客戶端不會由於等待服務返回而阻塞其它請求。
在請求/異步響應模式中,服務器端異步響應是在多處理器系統上能夠並行處理或者單處理上交錯執行,這使得當某個線程阻塞請求的同時其它線程得以繼續執行。但訪問共享資源時,須要保證其線程安全,能夠經過鎖,先進先出集合或者其它機制來處理線程安全的問題。
1.單體應用架構
當網站流量很小時,只須要將全部功能部署在一塊兒,以減小部署節點和成本
單體架構業務流程每每在同一個進程內部完成處理,不須要進行分佈式協做,它的工做原理以下:
圖 1-1 單體架構本地方法調用
2.垂直應用架構
當訪問量逐漸增大,單體架構壓力愈來愈大,將架構拆成互不相干的若干應用以提高效率,此時採用MVC、webAPI進行調用
3.分佈式微服務架構
當垂直應用愈來愈多,應用之間交互不可避免,能夠將各個獨立的業務模塊,部署成獨立的微服務,逐漸造成穩定的服務中心。
而Surging 微服務採用分佈式集羣部署方式,服務的消費者和提供者一般運行在不一樣的進程中,進程之間通訊採用RPC方式調用,它的工做原理以下:
圖1-2 Surging分佈式RPC調用
Surging微服務採用基於netty進行通訊,數據之間的傳遞經過序列化和反序列JSON,相比於本地方法調用,會產生以下問題:
1.數據序列化問題:微服務進程的通訊都須要通過序列化和反序列化,因數據結構不一致、數據類型的不支持、編碼錯誤都會形成數據轉化的失敗,從而致使調用失敗
2.網絡問題:常見的包括網絡超時、網絡閃斷、網絡阻塞等, 都會致使微服務遠程調用失敗。
每一個微服務都獨立打包部署,讓服務之間進行進程隔離,對於大型的互聯網項目,會有成百上千的微服務,一般不會百分百獨立部署,對於同一業務的微服務會打包部署在一塊兒,對於時延很是敏感,會合設在同一進程以內,採用本地方法調用。
不一樣的微服務合設在同一進程中,會產生如下問題:
Surging框架代碼邏輯一共劃分了8層,各個層的設計要點:
Surging 微服務的運行質量,除了自身的可靠性因素以外,還受到其它因素的影響,包括網絡,數據庫訪問,其它關聯的微服務的運行質量,可靠性設計,須要考慮上述綜合因素,總結以下:
4.1.1 網絡I/O
1.同步阻塞I/o 通訊:
即典型的請求/響應模式。 該模型最大的問題就是缺少彈性伸縮能力,當客戶端併發訪問量增長後,服務端的線程個數和客戶端併發訪問數呈1:1的正比關係,線程數量快速膨脹後,系統的性能將急劇降低,隨着訪問量的繼續增大,系統最終崩潰。
Surging 是基於Netty進行異步非阻塞I/O 通訊,即典型的請求/異步響應模式。此模式的優勢以下:
4.1.2 磁盤I/O
微服務對磁盤I/O的操做主要分爲同步文件操做和異步文件操做,
在Surging項目中,須要從註冊中心獲取路由信息緩存到本地,經過建立代理,負載均衡算法選擇Router,路由信息的緩存到採用的是心跳檢測的方式進行更新。
4.1.3 數據庫操做
通常來講文件 I/O、網絡訪問乃至於進程間同步通訊,以及本節所討論的 數據庫訪問等都較爲耗時,ado.net,Entity Framework以及其它ORM框架都提供了異步執行方法。
因爲大部分微服務採用同步接口調用,並且多個領域相關的微服務會部署在同一個進程中,很容易發生「雪崩效應」,即某個微服務提供者故障,致使調用該微服務的消費者、或者與故障微服務合設在同一個進程中的其它微服務發生級聯故障,最終致使系統崩潰。爲了不「雪崩效應」的發生,須要支持多種維度的依賴和故障隔離,
4.1.1 通訊鏈路隔離
因爲網絡通訊自己一般不是系統的瓶頸,所以大部分服務框架會採用多線程+單個通訊鏈路的方式進行通訊,原理以下所示:
4.1.2 調度資源隔離
4.1.2.1微服務之間隔離
當多個微服務合設運行在同一個進程內部時,能夠利用線程實現不一樣微服務之間的隔離。
對於核心的微服務,例如商品用戶註冊、計費、訂單等,能夠採用獨立部署的方式,實現高可用性。
微服務將整個項目解耦成各個獨立的業務模塊,部署成獨立的微服務,利用Docker 容器部署微服務能夠升級和擴容,而且有如下優勢:
高效:使用Docker部署微服務,微服務的啓動 和銷燬速度很是快,在高壓力時,能夠實現秒級彈性伸縮。
高性能:Docker 容器的性能接近邏輯,比VM高20%
隔離性:能夠實現高密度的部署微服務,並且是基於細粒度的資源隔離機制,實現微服務隔離,保證微服務的可靠性
可移植性:經過將運行環境和應用程序打包到一塊兒,來解決部署的環境依賴問題,真正作到跨平臺的分發和使用。可謂是一次編寫,處處運行。
除了Docker容器隔離,也可使用VM對微服務進行故障隔離,相比於Docker容器,使用VM進行微服務隔離存在以下優點:
1.微服務的資源隔離性更好,CPU、內存、網絡等能夠實現徹底的資源隔離。
2.對於已經完成硬件虛擬化的遺留系統,能夠直接使用已有的VM,而不須要在VM中從新部署Docker容器。
略
設計目標:
設計以下:
緩存中間件內部使用一致性哈希算法實現分佈式。設置的虛擬節點能均勻分佈。
緩存中間件暫時只實現Redis,MemoryCache作爲緩存服務。後期應該會實現CacheBase
緩存中間件後期會提供配置服務,方便管理緩存服務配置,以及顯示一些狀態信息
設計目標:
設計以下:
1.publisher: 是發佈者把消息事件Event經過Event Bus 發佈到Topic
2.Event bus::是事件總線,對於publisher 和 Subscriber 之間進行解耦,找到已經註冊的事件訂閱者,消息事件Event發送到topic
3.Topic: 是消息路由,對於訂閱者以廣播的形式,讓在線的Subscriber接收消息事件。
4.Subscriber:是訂閱者, 收到事件總線發下來的消息。即Handle方法被執行。注意參數類型必須和發佈者發佈的參數一致。
surging 0.0.0.1版本還有不少須要完善的地方,好比路由容錯,服務降級、熔斷,監控平臺和配置服務平臺,以及後續的第三方中間件的集成,這些任務都已經規劃到日程,再不久的未來會看到1.0穩定版本的發佈 ,若有興趣能夠加入QQ羣:542283494