由淺入深了解Thrift之微服務化應用架構


為什么選擇微服務

     一般情況下,業務應用我們都會采用模塊化的分層式架構,所有的業務邏輯代碼最終會在一個代碼庫中並統一部署,我們稱這種應用架構為單體應用。 單體應用的問題是,全部開發人員會共享一個代碼庫,不同模塊的邊界模糊,實現高內聚、松耦合極其困難。 肯定大家會碰到過這類場景,當嘗試去重構改進代碼時,改了一個地方好幾個其他模塊也需要同步改動, 當初划分的模塊邊界輕易被穿透,有人給這種應用的架構起了一個很形象的名字叫 “洋蔥架構”。

    Netflix是一家成功實踐微服務架構的互聯網公司,總結了一套行之有效的微服務方案。微服務架構強調 “微”,服務緊密圍繞業務領域,形成高度內聚的自治性。

更多的單體應用和微服務優劣勢請參看《微服務實戰(一):微服務架構的優勢與不足》

 

微服務特征 

業務能力建模:高內聚、松散耦合,暴露接口而隱藏實現細節

服務協作模型:中心化和去中心化

服務交互方式:RPC/REST等

自動化文化與環境:自動化構建、自動化測試、自動化部署

服務發布:灰度發布

服務部署:部署獨立性、失敗隔離性、可監控性;一服務一主機模型需要虛擬化、容器化

服務配置:中心化配置服務

服務流控:降級、限流

服務恢復:多考慮故障如何快速恢復服務而非如何避免故障發生 

 

當前業界比較成熟的微服務框架有Netflix的Karyon/Ribbon,Spring的Spring Boot/Cloud,阿里的Dubbo等。 

Netflix的微服務框架

Netflix是一家成功實踐微服務架構的互聯網公司,幾年前,Netflix就把它的幾乎整個微服務框架棧開源貢獻給了社區,這些框架和組件包括:

  • Eureka: 服務注冊發現框架
  • Zuul: 服務網關
  • Karyon: 服務端框架
  • Ribbon: 客戶端框架
  • Hystrix: 服務容錯組件
  • Archaius: 服務配置組件
  • Servo: Metrics組件
  • Blitz4j: 日志組件

微服務框架

1、服務注冊、服務發現、健康檢查

   如果我們采用進程內LB方案,那么服務自注冊一般統一做在服務器端框架中,健康檢查邏輯由具體業務服務定制,框架層提供調用健康檢查邏輯的機制,服務發現和負載均衡則集成在服務客戶端框架中。

2、RPC/REST和序列化

  框架層要支持將業務邏輯以HTTP/REST或者RPC方式暴露出來,HTTP/REST是當前主流API暴露方式,在性能要求高的場合則可采用Binary/RPC方式。針對當前多樣化的設備類型(瀏覽器、普通PC、無線設備等),框架層要支持可定制的序列化機制,例如,對瀏覽器,框架支持輸出Ajax友好的JSON消息格式,而對無線設備上的Native App,框架支持輸出性能高的Binary消息格式。

3、管理接口

  框架集成管理接口,一方面可以在線查看框架和服務內部狀態,同時還可以動態調整內部狀態,對調試、監控和管理能提供快速反饋。Spring Boot微框架的Actuator模塊就是一個強大的管理接口。對於框架層和服務的內部異常,如果框架層能夠統一處理並記錄日志,對服務監控和快速問題定位有很大幫助。

4、安全控制

  安全和訪問控制邏輯可以在框架層統一進行封裝,可做成插件形式,具體業務服務根據需要加載相關安全插件。

5、配置管理

  除了支持普通配置文件方式的配置,框架層還可集成動態運行時配置,能夠在運行時針對不同環境動態調整服務的參數和配置。

6、監控日志

  框架一方面要記錄重要的框架層日志、服務調用鏈數據,還要將日志、調用鏈數據等接口暴露出來,讓業務層能根據需要記錄業務日志數據。在運行環境中,所有日志數據一般由日志系統做進一步分析和處理。

7、統一錯誤處理

  對於框架層和服務的內部異常,如果框架層能夠統一處理並記錄日志,對服務監控和快速問題定位有很大幫助。

8、流控和容錯

  框架集成限流容錯組件,能夠在運行時自動限流和容錯,保護服務,如果進一步和動態配置相結合,還可以實現動態限流和熔斷。

 

負載均衡

1、集中式的負載均衡方案

     在服務消費者和服務提供者之間有一個獨立的LB,LB通常是專門的硬件設備如F5,或者基於軟件如LVS,HAproxy等實現。LB上有所有服務的地址映射表,通常由運維配置注冊,當服務消費方調用某個目標服務時,它向LB發起請求,由LB以某種策略(比如Round-Robin)做負載均衡后將請求轉發到目標服務。LB一般具備健康檢查能力,能自動摘除不健康的服務實例。

     服務消費方如何發現LB呢?通常的做法是通過DNS,運維人員為服務配置一個DNS域名,這個域名指向LB。

     方案優缺點:

     1)、單點問題,所有服務調用流量都經過LB,當服務數量和調用量大的時候,LB容易成為瓶頸,且一旦LB發生故障對整個系統的影響是災難性的。

     2)、LB在服務消費方和服務提供方之間增加了一跳(hop),有一定性能開銷。

2、進程內的負載均衡方案

           

      進程內LB方案將LB的功能以庫Library的形式集成到服務消費方進程里頭,該方案也被稱為軟負載(Soft Load Balancing)或者客戶端負載方案。這一方案需要一個服務注冊表(Service Registry)配合支持服務自注冊和自發現,服務提供方啟動時,首先將服務地址注冊到服務注冊表(同時定期報心跳到服務注冊表以表明服務的存活狀態,相當於健康檢查),服務消費方要訪問某個服務時,它通過內置的LB組件向服務注冊表查詢(同時緩存並定期刷新)目標服務地址列表,然后以某種負載均衡策略選擇一個目標服務地址,最后向目標服務發起請求。這一方案對服務注冊表的可用性(Availability)要求很高,一般采用能滿足高可用分布式一致的組件(例如Zookeeper, Consul, Etcd等)來實現。

     方案優缺點:

     1)、是一種分布式方案,LB和服務發現能力被分散到每一個服務消費者的進程內部,同時服務消費方和服務提供方之間是直接調用,沒有額外開銷,性能比較好。

     但由於該方案以客戶庫(Client Library)的方式集成到服務調用方進程里頭,

     2)、需要開發支持多種不同語言的客戶端,有一定的研發成本。  

     3)、客戶庫Library跟隨服務調用方發布到生產環境中,后續如果要對客戶庫Library進行升級,會有很大的維護成本。

   阿里開源的服務框架Dubbo也是采用類似機制。

3、主機獨立的負載均衡方案

      

     主機獨立LB進程方案,該方案是針對第二種方案的不足而提出的一種折中方案,原理和第二種方案基本類似,不同之處是,他將LB和服務發現功能從進程內移出來,變成主機上的一個獨立進程,主機上的一個或者多個服務要訪問目標服務時,他們都通過同一主機上的獨立LB進程做服務發現和負載均衡。

     方案優缺點:

     1)、是一種分布式方案,沒有單點問題,一個LB進程掛了只影響該主機上的服務調用方,服務調用方和LB之間是進程內調用,性能好,同時,該方案還簡化了服務調用方,不需要為不同語言開發客戶庫,LB的升級不需要服務調用方改代碼。  

     2)、不足是部署較復雜,環節多,出錯調試排查問題不方便。

服務前端路由

IDL+Nginx+AOP

 微服務除了內部相互之間調用和通信之外,最終要以某種方式暴露出去,才能讓外界系統(例如客戶的瀏覽器、移動設備等等)訪問到,這就涉及服務的前端路由,對應的組件是服務網關(Service Gateway)。

服務網關service Gateway

          

1、服務反向路由

2、安全認證和防爬蟲

3、限流和容錯

4、監控

5、日志

 

服務容錯

     當我們的業務逐漸復雜以后,服務之間的依賴關系也會有錯綜復雜,例如,一個前端請求一般會依賴於多個后端服務。由於,服務往往不是百分百可靠,服務可能會出錯或者產生延遲,如果一個應用不能對其依賴的故障進行容錯和隔離,那么該應用本身就處在被拖垮的風險中。在一個高流量的網站中,某個單一后端一旦發生延遲,可能在數秒內導致所有應用資源(線程,隊列等)被耗盡,造成所謂的雪崩效應(Cascading Failure),嚴重時可致整個網站癱瘓。

我們可以從不同的緯度避免和解決:

服務設計:

1、基礎服務

2、復雜業務服務

3、減少服務復雜的依賴,盡量保持簡單的依賴關系

容錯設計:

1、故障隔離、容錯

2、降級、限流

3、快速失敗(Fail Fast):直接拋出異常、可以返回空值或缺省值

 

(未完待續)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM