從技術角度討論微服務

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

 

微服務的兩個程度

1、服務化

  複雜的單體架構會有如下的挑戰:前端

  (1)項目啓動初期,須要尋找一個能儘可能涵蓋全部需求的開發語言,技術選型難度高;java

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

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

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

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

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

 

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

  服務化解耦後:後端

  (1)微服務能夠根據自身業務特徵選擇合適的開發語言或數據庫;

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

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

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

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

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

 

2、容器化

  容器(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(綠色箭頭)。

 

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

 

服務註冊發現

 1、最簡單的服務註冊發現

  

  我認爲最簡單的服務註冊發現是直接經過IP端口進行訪問,這種方式適用於單個實例的服務,但若是API Y是多個實例,那麼須要藉助相似虛擬IP(VIP)等技術。

 

 2、基於中間件的服務註冊發現

  

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

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

  

3、基於容器治理平臺的服務註冊發現

  

   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,無語言侵入性,但負載均衡的靈活性比中間件的方式稍微低一些。

 

配置管理

 1、最簡單的配置管理

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

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

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

 

2、基於中間件的配置管理

   

 

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

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

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

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

 

3、基於容器治理平臺的配置管理

   

  這種方式的典型表明是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來實現共用的方式;使得開發更加靈活,也使得開發能夠更加關注於業務,而非各類邊邊角角的公共(輪子)功能。

相關文章
相關標籤/搜索