當前位置:
首頁 > 最新 > 從技術角度討論微服務

從技術角度討論微服務

本文希望從技術角度來探討下微服務,因此,不會過多地談及如何根據業務進行微服務劃分,更多是介紹微服務的相關技術,微服務的業務劃分方法可參考「領域驅動設計「相關方法論。


微服務的兩個程度

一、服務化

複雜的單體架構會有以下的挑戰:

(1)項目啟動初期,需要尋找一個能盡量涵蓋所有需求的開發語言,技術選型難度高;

(2)工程龐大,組件、中間件繁多,編譯時間長;開發環境複雜,需要安裝大量的輔助軟體,環境準備時間長;

(3)團隊無效溝通多,溝通成本高;

(4)部署環境依賴大,某個組件的問題可能導致整個系統無法運行;

(5)新功能添加或者bug修復的時候,會影響現有功能,引發新的(未知)問題,添加單元測試難度大;

(6)版本回滾顆粒度大,靈活性差。

以上幾點都是實際項目中遇到的問題,如果你也遇到了同樣的問題,那麼服務化是較好的解決方案。

服務化解耦後:

(1)微服務可以根據自身業務特徵選擇合適的開發語言或資料庫;

(2)微服務的開發者只需要安裝該服務相關的輔助軟體;

(3)溝通多集中在微服務團隊中,與周邊(或公共)微服務有交集時才產生相應的溝通;

(4)部署環境依賴小,某個微服務部署失敗僅影響該微服務(或周邊幾個微服務);

(5)功能調整,如果介面沒有調整,基本不會影響其它微服務,添加單元測試、介面測試難度低,自動化(回歸)測試覆蓋率高;

(6)版本回歸最小單位為某個微服務,顆粒度小,可更好地實現藍綠部署、A/B測試、灰度(金絲雀)發布。


容器(docker)具有輕量、環境依賴低、啟動速度快等特點;

虛擬化技術(openstack)負責IaaS層(存儲、計算、網路)資源的調度;

容器治理平台(Kubernetes、docker swarm)配合資源監控對容器進行靈活調度;

以上3種技術極大地提高了微服務的橫向(彈性)伸縮以及高可用的能力,使微服務具備更好的高並發處理能力。

配合DevOps,CI/CD等工具及技術提升了團隊快速響應、持續交付的能力。

我認為,團隊應該基於產品或項目實際情況選擇合適的微服務程度。


微服務基礎技術架構

我認為,當前使用前後端分離的開發模式還是十分有好處的,關於前後端分離的描述,可參考我之前的《淺談開發模式及架構發展》。

Web A/B/C/...是幾個純前端項目,可以根據實際情況在不同項目中使用Angularjs、Vuejs或Reactjs等框架進行開發;

API X/Y/Z/...是幾個API項目,供Web或者App調用,可以根據實際情況使用.Net Core、Java或python等語言進行開發;

也可以根據帶寬或性能需要,讓Web或API啟動多份示例。

基本交互:

瀏覽器經過網關從服務端獲取網站的html及js(橙色箭頭);

Web通過url或ajax經過網關訪問服務端API,App通過類Http Client方式經過網關訪問服務端API(灰色箭頭);

API X/Y/Z/...註冊到服務中心(藍色箭頭);

Web A/B/C/...、API X/Y/Z/...從配置中心讀取各自的配置(紫色箭頭);

API X通過服務中心調用API Z(綠色箭頭)。

因此,微服務的三個基礎組成部分分別是服務註冊發現,配置管理以及網關。


服務註冊發現

我認為最簡單的服務註冊發現是直接通過IP埠進行訪問,這種方式適用於單個實例的服務,但如果API Y是多個實例,那麼需要藉助類似虛擬IP(VIP)等技術。

API Y實例1/2/.../n啟動時,會把自己的信息註冊到服務中心(自上報);API X需要調用API Y,會先從服務中心中獲取API Y服務實例的IP埠列表;然後根據特定的策略(隨機,網路情況,權重等)篩選出一個實例進行調用,負載均衡是在客戶端(調用方)實現的。

這種方式的典型代表是Spring Cloud Eureka,如果服務中心down掉了,那麼會影響整個系統,因此,要保證服務中心的高可用;另外,需要有特定的jdk/sdk和服務中心進行交互,如Java的FeignClient(集成了ribbon實現服務的負載均衡),steeltoe的DiscoveryHttpClientHandler(隨機選擇實現服務的負載均衡),有一定的語言侵入性。


API Y實例1/2/.../n部署啟動時,治理平台會給它們分配IP埠,並記錄在服務中心;API X需要調用API Y,會基於dns,通過API Y的服務名或集群 IP(Cluster IP,類似於Virtual IP)加埠進行訪問。負載均衡由治理平台負責,是在服務端(平台)實現的。

這種方式的典型代表是docker swarm以及Kubernetes,服務註冊發現的高可用由平台保證,因為基於dns,普通的http客戶端就可以進行Api訪問,如java的restTemplate或C#的HttpClient,無語言侵入性,但負載均衡的靈活性比中間件的方式稍微低一些。


配置管理

最簡單的配置管理就是平時常用的配置管理,如java的application.properties、.net的web.config、.net core的appsettings.json等,基本是和應用程序一起,能夠兼容多個環境(開發、測試、生產)。

但當我們的程序需要啟用多份的時候,這種簡單的配置管理方式遇到了挑戰,配置的更新需要手動更新各個實例的配置文件,繁瑣且容易出錯(遺漏、修改錯誤或環境依賴)。

這也是微服務中面臨的一個主要挑戰。


這種方式的典型代表是Spring Cloud Config Server。

API X、Y...會通過Url訪問配置中心,通過心跳(2s)來確認配置中心的健康以及檢測配置內容的更新。

其中,application.yaml用於保存各個微服務的公共配置,.yaml用於保存微服務的私有配置。

和Eureka一樣,使用者需要自己保證Config Server的高可用,否則,配置中心down掉的話,整個系統的配置信息就會亂套;另外,也需要有特定的jdk/sdk和配置中心進行交互;配置文件的格式基本也限制於yaml格式。


這種方式的典型代表是Kubernetes ConfigMap。

部署、升級、增加API X、Y...實例時,Kubernetes會按照設置,把對應的配置文件放置到容器(docker)指定的位置,也可以是環境變數。

配置中心的高可用由治理平台保證,微服務不需要使用特定的jdk/sdk和配置中心交互,只需要解析本地路徑的某些文件,文件格式可以根據需要選擇(json,xml,yaml,properties)。

微服務公共配置與私有配置也可以實現,但需要語言支持,比如.net core,詳細的可以參考我之前的文章《你可能不知道的.Net Core Configuration》。


網關

網關作為微服務的統一出口,一般需要完成以下任務:反向代理,跨域處理,負載均衡,流量控制,緩存,日誌,公共功能(如認證)等,常用的網關中間件有Nginx,Spring Cloud Zuul,Kong,Ocelot等。

或許有人會問,像公共功能(如認證)這些,在過濾器(filter)里做就好了啊,為什麼要在網關做,沒看出什麼優勢。I think it is a good call.

確實,像認證這些功能的確可以在過濾器里做,但是,如果過濾器需要升級,那麼每個微服務都要進行升級;另外一種情況是,如果微服務是使用不同語言編寫的,那麼還需要提供多個版本的filter;更為惡劣的可能是該語言不支持filter,或者像單點登錄這些公共模塊沒有提供該語言的jdk或sdk;還有一種比較特殊的情況是,可能在不同的環境系統需要有不同的認證機制,如對接第三方的認證系統。使用網關就能比較好的解決以上問題。


下一代微服務

既然可以通過部署一個網關,讓所有請求都經過它來實現一些公共的功能,那麼有沒有可能使微服務的請求經過一個特定的「層」,來實現一些特定的功能(如調用鏈、熔斷,服務調用認證,請求限制等)呢?答案是肯定的。

我認為Kubernetes其中一個強大的設計是,它的最小單位是pod,而不是容器(container);一個pod裡面可以有多個容器,而且它們可以共享網路,共享存儲。

可以通過在pod裡面部署一個業務容器,同時也部署一個小型的sidecar容器,讓請求到達業務容器之前,先經過sidecar容器(起到了filter的作用),在sidecar容器中實現調用鏈、熔斷,服務調用認證,請求限制等功能,這樣就可以通過基於部署的方式解決語言限制的問題。

目前可以選擇Istio或Linkerd來實現上述效果。


簡單總結

我認為,從架構的層面來看微服務架構,應該是這樣的:

擴展性:降低複雜系統的耦合度、溝通成本以及系統複雜度,需求快速響應;

伸縮性:可以通過增加資源的方式來快速應對海量並發(僅僅是並發層面,大數據量還是需要根據業務進行分片或分割);

穩定性:微服務治理平台,PaaS平台保證了系統的高可用性,可以降低業務的中斷時間;

安全性:和傳統架構的要求差別不大,但是由於網關和網格(Service Mesh)的存在,使得安全處理,APM等的實現更加簡單。

另外,我認為微服務可以通過部署的方式來實現功能或模塊的復用,一定程度上代替了過往通過jdk/sdk來實現共用的方式;使得開發更加靈活,也使得開發可以更加關注於業務,而非各種邊邊角角的公共(輪子)功能。

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

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


請您繼續閱讀更多來自 dotNET跨平台 的精彩文章:

小白帶你入坑xamarin系列之環境搭建和準備
dotnet core webapi+vue 搭建前後端完全分離web架構(一)

TAG:dotNET跨平台 |