前言
關于微服務的架構,我們前面的文章中給出了大概的說明,也就是說微服務架構的應用與傳統的大型單體應用架構相比,最大的區別在于從原來的基于單一應用進程的設計轉變為基于服務集群以及云服務網絡的設計。
從而需要我們轉變開發的思路,調整開發和運維的組織架構來更好的適應微服務架構應用開發和運維。
當然微服務架構應用的開發和運維中一個重要的挑戰是如何管理被拆分出來的大量的單一功能的組件化服務,特別是當我為實現服務的健壯性和可伸縮性時,需要部署服務成高可用型架構或者集群架構的多個服務節點來提供統一的功能服務。
這就要求我們必須擁有一個強壯文檔的底層網絡通信服務作為基礎設施,能夠讓我們的高可用性架構或者集群式部署的應用成為可能。
傳統應用架構與微服務
在過去傳統的應用程序架構開發過程中,比如是用JAVA開發的大型單體應用,它是基于同一個JVM來開發的,也就是說整個應用程序是運行在一個單一的JVM環境里的,各個功能組件和分層都只是同一個JVM內部運行的線程而已,功能之間的相互通信都是線程間的數據共享和方法調用。
我們如果需要一個高可用性架構部署都是使用的整個應用的冗余部署,對于那些狀態會話的數據一致性問題,我們需要單獨設計數據一致性方案,比如共享緩存服務等,來實現高可用性架構或者集群部署中的用戶數據的一致性。
顯然這種粗粒度的冗余部署只能在一定程度上環節服務的可擴展性壓力,但是無法完全解決問題,并且其解決問題的方案都存在一定的局限性。
無法真正做到較高的可靠性,穩定性,可擴展性和處理能力的彈性。同時由于這種部署是全系統冗余,造成了很多非常用性組件算力的冗余浪費。
而對于那些對并發處理能力較高的服務卻無法給予所需的滿足。因為組件之間的依賴性太強,造成可能某個組件出現問題,就會使得整個應用程序無法正常運行提供服務,同時在出現問題時,我們也無法及時發現問題原因,因為在同一個JVM進程中運行的內容太多,識別錯誤和問題成本太高。
為此我們在企業級應用程序開發架構中引入過SOA架構,使用統一的企業級總線服務作為集成企業內部各系統和服務的數據交換和集成。
同時還有進一步提出的基于遠程方法調用的RPC框架,這些都在一定程度上為我們開發大型的分布式應用系統提供了解決方案。
微服務架構設計
在微服務架構設計中,我們需要遵循功能單一原則,并且能夠盡量的降低組件之間的相互耦合,增強功能內部實現的聚合能力,我們在設計時通常采用領域驅動設計(DDD)原則。
即根據業務領域的需求對業務實體進行識別,同時找出業務實體的根組件,從而以根組件為業務處理的入口點來統一管理該領域內的非實體組件和數據的操作處理。
每個業務模塊之間的通信都必須通過各業務模塊的根組件來完成,如此該設計思想完全契合我們微服務框架的設計。
也就是對外的交互通信都有唯一的入口控制,組件與組件的通信都必須通過公開的遠程方法調用接口或者以標準消息格式發送事件,由對應的服務接口或者相關事件的訂閱者服務來處理。
云原生應用與微服務
隨著云計算和PaaS服務的出現,我們的應用程序開始轉向了基于云服務器開發的模式,為此HeroKu總結出了開發Cloud Native應用的12-Factory原則。
從設置基準代碼庫,到開發依賴聲明,不同環境的配置分離,以及后端服務定義,整個應用程序的構建,發布和運行,在到進程和端口綁定設置,并發處理過程日志,以及對服務的進程管理等等多個方面進行了規范說明,目前這些基本上都適用于我們的微服務框架應用的開發。
就目前微服務開發主要是基于云服務架構部署的應用開發,所以我們在開發之前需要首先確定服務的形式和后端服務劃分,包括相互之間通信方式等。
由于微服務架構的靈活性,讓我們可以根據具體服務的特點來選擇相適應的數據存儲服務,同時在由于基于云服務需要對抗網絡的脆弱性。
也就是說我們的網絡時常是不穩定的,需要處理這種網絡的不穩定對于服務造成的影響。
微服務架構組件
一般情況下,在設計時我們會都是以RESTful API服務形式對外部用戶提供服務接口,而在組件服務集群內部則采用RPC架構或者RESTful結構。
由于每個微服務組件都是一個獨立運行的節點,所以微服務之間的相互調用都是遠程方法調用模式,當然他們之間調用所使用的協議和方式可以有多種,有基于RPC框架的,也有基于網絡套接字HTTP協議的。
由于外部用戶訪問我們的系統時的請求往往都是某種綜合的業務需求,而我們微服務架構實現時都是以組件服務節點運行的單一功能的服務請求處理,如此我們就需要對用戶請求做一些路由過濾以及拆分和結果合并處理。為此我們在整個微服務架構應用設計中引入了前端控制模式實現,即網關服務。
網關服務同樣被設計成微服務組件,所以可以采用高可用性架構或者網關服務集群部署,來提高穩定性,以及針對某些特定服務請求的過濾和分發處理。
比如Netflix的Zuul組件就是一個基于JVM的不錯的API網關設計,我們在開發微服務架構應用時,通常基于它來開發一些附加服務比如用戶身份驗證,鑒權,流量監控,限流,數據過濾等功能。
由于網關作為整個系統對外提供服務的入口,它負責對請求的處理非常重要。同時為我們的應用管理提供了極大的靈活性。在一個微服務架構設計中,一個好的智能化的網關設計,將對整個應用系統起著至關重要的作用。
同時由于我們的內部每個功能服務組件都是獨立運行的節點容器,為了某個服務的健壯性我們往往會考慮采用集群化部署的高可用性架構。
關于負載均衡組件
作為某個單一功能將會有一個微型的服務節點集群來提供服務處理,為此對于功能調用的請求就需要一個負載均衡服務組件來負責監控各個服務節點運行狀態并為其分配要處理的請求。
所以在微服務架構中,負載均衡服務也是一個非常重要的設計實現。
負載均衡服務,本質上就是點對點服務連接選擇和建立的實現。我們可以把它簡單的想象成一個服務節點運行一個服務進程維護一個所有服務節點的狀態列表,該服務節點會通過心跳請求不間斷的去試圖連接這些節點得到回應以檢測各個服務節點的運行狀態。
然后根據某種算法比如輪詢,加權指數等算法將請求映射的路徑解析到服務節點列表中的服務節點上,從而將請求的地址映射到具體的服務節點,轉發請求到該節點,由其對該請求進程處理。
顯然這樣的負載均衡服務屬于非系統功能性組件,應該有基礎架構提供實現。我們可以看到Spring Cloud框架里提供了Ribbon組件等。
其實Ribbon也是基于Eureka組件添加了路由算法來實現的。
我們知道Spring Cloud 的注冊和發現服務組件Eureka是基于Netty開發的Client/Server模式的網絡基礎架構服務,它采用所謂的邊車模式在我們具體服務組件的運行容器中,添加一個網絡客戶端線程,維護一個注冊服務列表,同樣的Ribbon也有一個這樣的邊車進程,可以通過它獲取正在運行的服務組件信息,從而通過一定的負載均衡算法將請求映射給可用的服務組件。
微服務開發框架
我們知道在微服務具體開發的過程中Spring Boot是一個開發利器,因為Spring Boot是對整個Spring框架開發的集成和簡化,它將web容器作為組件嵌入到了開發框架中。
同時它為我們開發應用程序提供了簡化的依賴包,以及使用Spring容器對于受托管組件的配置管理,提供了多種常用的默認配置和必備組件組合方案的預加載。
并且為Spring容器的配置提供了基于鍵值對的文本格式或者yml格式的配置接口。配合開發配置管理工具比如Maven或者Gradle等,我們很容易的將開發的應用程序打包成Jar文件。
從而在JVM環境里直接運行它,這為我們開發微服務組件項目提供了非常簡單便捷的工程框架。
總結
總之,微服務應用開發是一種從就有的遠程方法調用RPC框架和基于網絡的HTTP請求處理為基礎發展出來的一種應用程序組件化實現形式。它也是應對當前應用程序云端化,服務組件化以及SaaS,Servless等架構應用的必然要求。也就是說,我們必須將我們傳統的單體綜合應用系統打散成一個個能夠獨立運行且相互之間的依賴是通過標準的進程間通信或者網絡訪問為基礎的節點集群部署架構的應用。
這種結構的開發復雜性比起傳統的應用程序來說大大的提高了,但是它能夠通過功能單一簡化提高管理和運維效率,降低對其它功能組件的影響,從而更好的做到服務的穩定性和可靠性,同時還能根據網絡應用的特點,提高請求處理的彈性。 這些都是要求我們在設計和開發過程中轉變思路,基于現有成熟的基礎架構來構建新一代應用。