天天看點

基于微服務和Docker的PaaS雲平台架構設計

基于微服務架構和Docker容器技術的PaaS雲平台建設目标是給我們的開發人員提供一套服務快速開發、部署、運維管理、持續開發持續內建的流程。平台提供基礎設施、中間件、資料服務、雲

伺服器

等資源,開發人員隻需要開發業務代碼并送出到平台代碼庫,做一些必要的配置,系統會自動建構、部署,實作應用的靈活開發、快速疊代。在系統架構上,PaaS雲平台主要分為微服務架構、Docker容器技術、DveOps三部分,這篇文章重點介紹微服務架構的實施。

  實施微服務需要投入大量的技術力量來開發基礎設施,這對很多公司來說顯然是不現實的,别擔心,業界已經有非常優秀的開源架構供我們參考使用。目前業界比較成熟的微服務架構有Netflix、Spring Cloud和阿裡的Dubbo等。Spring Cloud是基于Spring Boot的一整套實作微服務的架構,它提供了開發微服務所需的元件,跟Spring Boot一起使用的話開發微服務架構的雲服務會變的很友善。Spring Cloud包含很多子架構,其中Spring Cloud Netflix是其中的一套架構,在我們的微服務架構設計中,就使用了很多Spring Cloud Netflix架構的元件。Spring Cloud Netflix項目的時間還不長,相關的文檔資料很少,部落客當時研究這套架構啃了很多英文文檔,簡直痛苦不堪。對于剛開始接觸這套架構的同學,要搭建一套微服務應用架構,可能會不知道如何下手,接下來介紹我們的微服務架構搭建過程以及需要那些架構或元件來支援微服務架構。

  為了直接明了的展示微服務架構的組成及原理,部落客畫了一張系統架構圖,如下:

基于微服務和Docker的PaaS雲平台架構設計

  從上圖可以看出,微服務通路大緻路徑為:外部請求 →

負載均衡

→ 服務

網關

(GateWay)→ 微服務 → 資料服務/消息服務。服務

和微服務都會用到服務注冊和發現來調用依賴的其他服務,各服務叢集都能通過配置中心服務來獲得配置資訊。

服務網關(GateWay)

  網關是外界系統(如:用戶端浏覽器、移動裝置等)和企業内部系統之間的一道門,所有的用戶端請求通過網關通路背景服務。為了應對高并發通路,服務網關以叢集形式部署,這就意味着需要做

,我們采用了亞馬遜EC2作為虛拟雲

,采用ELB(Elastic Load Balancing)做負載均衡。EC2具有自動配置容量功能,當使用者流量達到尖峰,EC2可以自動增加更多的容量以維持虛拟主機的性能。ELB彈性負載均衡,在多個執行個體間自動配置設定應用的傳入流量。為了保證安全性,用戶端請求需要使用https加密保護,這就需要我們進行SSL解除安裝,使用Nginx對加密請求進行解除安裝處理。外部請求經過ELB負載均衡後路由到GateWay叢集中的某個GateWay服務,由GateWay服務轉發到微服務。服務網關作為内部系統的邊界,它有以下基本能力:

  1、動态路由:動态的将請求路由到所需要的後端服務叢集。雖然内部是複雜的分布式微服務網狀結構,但是外部系統從網關看就像是一個整體服務,網關屏蔽了後端服務的複雜性。

  2、限流和容錯:為每種類型的請求配置設定容量,當請求數量超過閥值時抛掉外部請求,限制流量,保護背景服務不被大流量沖垮;黨内部服務出現故障時直接在邊界建立一些響應,集中做容錯處理,而不是将請求轉發到内部叢集,保證使用者良好的體驗。

  3、身份認證和安全性控制:對每個外部請求進行使用者認證,拒絕沒有通過認證的請求,還能通過通路模式分析,實作反爬蟲功能。

  4、監控:網關可以收集有意義的資料和統計,為背景服務優化提供資料支援。

  5、通路日志:網關可以收集通路日志資訊,比如通路的是哪個服務?處理過程(出現什麼異常)和結果?花費多少時間?通過分析日志内容,對背景系統做進一步優化。

  我們采用Spring Cloud Netflix架構的開源元件Zuul來實作網關服務。Zuul使用一系列不同類型的過濾器(Filter),通過重寫過濾器,使我們能夠靈活的實作網關(GateWay)的各種功能。

服務注冊與發現

  由于微服務架構是由一系列職責單一的細粒度服務構成的網狀結構,服務之間通過輕量機制進行通信,這就引入了服務注冊與發現的問題,服務的提供方要注冊報告服務位址,服務調用放要能發現目标服務。我們的微服務架構中使用了Eureka元件來實作服務的注冊與發現。所有的微服務(通過配置Eureka服務資訊)到Eureka伺服器中進行注冊,并定時發送心跳進行健康檢查,Eureka預設配置是30秒發送一次心跳,表明服務仍然處于存活狀态,發送心跳的時間間隔可以通過Eureka的配置參數自行配置,Eureka伺服器在接收到服務執行個體的最後一次心跳後,需要等待90秒(預設配置90秒,可以通過配置參數進行修改)後,才認定服務已經死亡(即連續3次沒有接收到心跳),在Eureka自我保護模式關閉的情況下會清除該服務的注冊資訊。所謂的自我保護模式是指,出現網絡分區、Eureka在短時間内丢失過多的服務時,會進入自我保護模式,即一個服務長時間沒有發送心跳,Eureka也不會将其删除。自我保護模式預設為開啟,可以通過配置參數将其設定為關閉狀态。

  Eureka服務以叢集的方式部署(在部落客的另一篇文章中詳細介紹了Eureka叢集的部署方式),叢集内的所有Eureka節點會定時自動同步微服務的注冊資訊,這樣就能保證所有的Eureka服務注冊資訊保持一緻。那麼在Eureka叢集裡,Eureka節點是如何發現其他節點的呢?我們通過DNS伺服器來建立所有Eureka節點的關聯,在部署Eureka叢集之外還需要搭建DNS伺服器。

  當網關服務轉發外部請求或者是背景微服務之間互相調用時,會去Eureka伺服器上查找目标服務的注冊資訊,發現目标服務并進行調用,這樣就形成了服務注冊與發現的整個流程。Eureka的配置參數數量很多,多達上百個,部落客會在另外的文章裡詳細說明。

微服務部署

  微服務是一系列職責單一、細粒度的服務,是将我們的業務進行拆分為獨立的服務單元,伸縮性好,耦合度低,不同的微服務可以用不同的語言開發,每一個服務處理的單一的業務。微服務可以劃分為前端服務(也叫邊緣服務)和後端服務(也叫中間服務),前端服務是對後端服務做必要的聚合和剪裁後暴露給外部不同的裝置(PC、Phone等),所有的服務啟動時都會到Eureka伺服器進行注冊,服務之間會有錯綜複雜的依賴關系。當網關服務轉發外部請求調用前端服務時,通過查詢服務系統資料庫就可以發現目标服務進行調用,前端服務調用後端服務時也是同樣的道理,一次請求可能涉及到多個服務之間的互相調用。由于每個微服務都是以叢集的形式部署,服務之間互相調用的時候需要做負載均衡,是以每個服務中都有一個LB元件用來實作負載均衡。

  微服務以鏡像的形式,運作在Docker容器中。Docker容器技術讓我們的服務部署變得簡單、高效。傳統的部署方式,需要在每台伺服器上安裝運作環境,如果我們的伺服器數量龐大,在每台伺服器上安裝運作環境将是一項無比繁重的工作,一旦運作環境發生改變,就不得不重新安裝,這簡直是災難性的。而使用Docker容器技術,我們隻需要将所需的基礎鏡像(jdk等)和微服務生成一個新的鏡像,将這個最終的鏡像部署在Docker容器中運作,這種方式簡單、高效,能夠快速部署服務。每個Docker容器中可以運作多個微服務,Docker容器以叢集的方式部署,使用Docker Swarm對這些容器進行管理。我們建立一個鏡像倉庫用來存放所有的基礎鏡像以及生成的最終傳遞鏡像,在鏡像倉庫中對所有鏡像進行管理。

服務容錯

  微服務之間存在錯綜複雜的依賴關系,一次請求可能會依賴多個後端服務,在實際生産中這些服務可能會産生故障或者延遲,在一個高流量的系統中,一旦某個服務産生延遲,可能會在短時間内耗盡系統資源,将整個系統拖垮,是以一個服務如果不能對其故障進行

隔離

和容錯,這本身就是災難性的。我們的微服務架構中使用了Hystrix元件來進行容錯處理。Hystrix是Netflix的一款開源元件,它通過熔斷模式、

模式、回退(fallback)和限流等機制對服務進行彈性容錯保護,保證系統的穩定性。

  1、熔斷模式:熔斷模式原理類似于電路熔斷器,當電路發生短路時,熔斷器熔斷,保護電路避免遭受災難性損失。當服務異常或者大量延時,滿足熔斷條件時服務調用方會主動啟動熔斷,執行fallback邏輯直接傳回,不會繼續調用服務進一步拖垮系統。熔斷器預設配置服務調用錯誤率閥值為50%,超過閥值将自動啟動熔斷模式。服務隔離一段時間以後,熔斷器會進入半熔斷狀态,即允許少量請求進行嘗試,如果仍然調用失敗,則回到熔斷狀态,如果調用成功,則關閉熔斷模式。

  2、隔離模式:Hystrix預設采用線程隔離,不同的服務使用不同的線程池,彼此之間不受影響,當一個服務出現故障耗盡它的線程池資源,其他的服務正常運作不受影響,達到隔離的效果。例如我們通過andThreadPoolKey配置某個服務使用命名為TestThreadPool的線程池,實作與其他命名的線程池隔離。

  3、回退(fallback):fallback機制其實是一種服務故障時的容錯方式,原理類似Java中的異常處理。隻需要繼承HystixCommand并重寫getFallBack()方法,在此方法中編寫處理邏輯,比如可以直接抛異常(快速失敗),可以傳回空值或預設值,也可以傳回備份資料等。當服務調用出現異常時,會轉向執行getFallBack()。有以下幾種情況會觸發fallback:

  1)程式抛出非HystrixBadRequestExcepption異常,當抛出HystrixBadRequestExcepption異常時,調用程式可以捕獲異常,沒有觸發fallback,當抛出其他異常時,會觸發fallback;

  2)程式運作逾時;

  3)熔斷啟動;

  4)線程池已滿。

  4、限流: 限流是指對服務的并發通路量進行限制,設定機關時間内的并發數,超出限制的請求拒絕并fallback,防止背景服務被沖垮。

  Hystix使用指令模式HystrixCommand包裝依賴調用邏輯,這樣相關的調用就自動處于Hystrix的彈性容錯保護之下。調用程式需要繼承HystrixCommand并将調用邏輯寫在run()中,使用execute()(同步阻塞)或queue()(異步非阻塞)來觸發執行run()。

動态配置中心

  微服務有很多依賴配置,某些配置參數在服務運作期間可能還要動态修改,比如:根據通路流量動态調整熔斷閥值。傳統的實作資訊配置的方法,比如放在xml、yml等配置檔案中,和應用一起打包,每次修改都要重新送出代碼、打包建構、生成新的鏡像、重新啟動服務,效率太低,這樣顯然是不合理的,是以我們需要搭建一個動态配置中心服務支援微服務動态配置。我們使用Spring Cloud的configserver服務幫我們實作動态配置中心的搭建。我們開發的微服務代碼都存放在git伺服器私有倉庫裡面,所有需要動态配置的配置檔案存放在git伺服器下的configserver(配置中心,也是一個微服務)服務中,部署到Docker容器中的微服務從git伺服器動态讀取配置檔案的資訊。當本地git倉庫修改代碼後push到git伺服器倉庫,git服務端hooks(post-receive,在服務端完成代碼更新後會自動調用)自動檢測是否有配置檔案更新,如果有,git服務端通過消息隊列給配置中心(configserver,一個部署在容器中的微服務)發消息,通知配置中心重新整理對應的配置檔案。這樣微服務就能擷取到最新的配置檔案資訊,實作動态配置。

  以上這些架構或元件是支撐實施微服務架構的核心,在實際生産中,我們還會用到很多其他的元件,比如日志服務元件、消息服務元件等等,根據業務需要自行選擇使用。在我們的微服務架構實施案例中,參考使用了很多Spring Cloud Netflix架構的開源元件,主要包括Zuul(服務網關)、Eureka(服務注冊與發現)、Hystrix(服務容錯)、Ribbon(用戶端負載均衡)等。這些優秀的開源元件,為我們實施微服務架構提供了捷徑。

  以上篇幅主要介紹了微服務架構的基本原理,其中有些比較細節的東西,比如Eureka的各項參數配置說明、動态配置中心搭建過程等,部落客會在其他的文章中做出詳細的說明,供大家參考。

原文釋出時間為:2018-06-5

本文作者:風中程式猿

本文來自雲栖社群合作夥伴“

IT168

”,了解相關資訊可以關注“

”。