天天看點

基于微服務的分布式應用開發

本文講的是<b>基于微服務的分布式應用開發</b>【編者的話】本文是有關使用微服務開發分布式應用的經驗之談,包括微服務的優勢以及Spring Cloud架構的簡要介紹等。

微服務架構設計模式對于單塊設計模式而言有很多優點。核心思想就是将單個巨大的應用劃分成互聯的不同應用。與單塊應用類似,每個微服務都有其自己的層級架構。

使用下列的模式,微服務可以輕易取得如下優點:

可擴充性。 一款典型的應用會使用3個方向的擴充。X軸擴充是指橫向擴充應用,Y軸擴充是指劃分不同的應用功能,Z軸擴充是指對于資料的分區(partioning)和分片(sharding)。當Y軸擴充應用到單塊應用時,該應用就會被打散,按照符合微服務特性的業務功能,形成許多更小的單元。

模式:每個微服務有其隔離的執行個體或容器。服務級别的負載均衡可以通過将相同服務托管于多個執行個體實作。

可用性 。如同相同的微服務會托管于多個執行個體中一樣,微服務會部署于不同的執行個體中,這使整個系統高度可用。

模式:服務級别的負載均衡可被用以實作高可用性,斷路器模式可被用以實作容錯,服務配置和服務發現可使發現新服務以通訊成為可能。

持續部署 。每個微服務均是獨立的。這就導緻任何服務均可獨立于其它服務完成部署,進而達到更加快速且可持續性的部署目标。

松耦合 。微服務提供不同的方式實作松耦合。每個微服務都應在服務級别有其自身的層級架構,并且在使用資料庫作為持久層時,它運作于自己的獨立環境中。

技術多樣性 。将微服務視為隔離的特性,多種技術的混合可以用于實作服務于整體應用的多種微服務。

高效成本 。服務執行個體可以基于應用使用率進行優化。低價執行個體可以用以最低優先的服務,而高價執行個體則可以用到關鍵業務服務。

性能 。考慮到微服務技術多樣化的優點,這會對性能有直接影響。例如,高阻塞率的服務調用在進線程技術棧中實作,CPU密集型服務在多線程技術棧中實作。

<a href="http://dockerone.com/uploads/article/20170112/0f56e0b6cf13ba8af24794ea7b7ca526.jpg" target="_blank"></a>

和單塊架構相比,微服務也有一些缺點。

諸如,和單塊應用相比,開發和管理分布式應用很困難。微服務需要程序間通訊(IPC)機制以使不同微服務之間得以通訊,當然這可能會對性能有點影響(取決于網絡帶寬)。

以下是為了實作高效微服務需要實作的功能:

對于IPC,每個微服務都應該使用Rest調用或RPC來調用其它微服務。

一個微服務可能會與單個或多個微服務通訊。一個服務可能會是不可用的,或者因為高負載或某種服務錯誤,而無法在限定時間内響應。為了應對這種場景,應該有部分故障或復原機制。

部署一款基于微服務的應用相比單塊應用而言會更加複雜,因為基于微服務的應用有不同的服務,并且每個服務可能會運作在不同的容器或執行個體上。是以需要一種服務注冊和發現機制,來完成想要通訊的新服務的注冊和發現。

一個用戶端微服務可能會因為單個功能來調用多個遠端的微服務。這可能會導緻跨網絡rest或RPC的高負載調用。是以需要一個服務網關,它會接受來自微服務的一個調用,然後内部分發這個調用給多個本地服務調用(對于服務網關而言是本地的),将這些服務的結構彙總,并傳回給用戶端微服務。

當同一個微服務托管于同一主機的不同容器中時,這裡就需要一個服務級的負載均衡來分發負載,并實作災備機制。

分布式應用也需要某種中心化日志架構,是以所有的資料可以被集中并生成日志資料。

自行實作上述的所有特性是很複雜的,會占用大量時間,并且會使開發者消耗大量時間來開發和測試基礎架構配置。然而,如果你已經具備了上述的一切,那麼你就隻需要聚焦于業務邏輯了。

Spring Cloud的許多元件來自Netflix開源軟體中心(Netflix OSS),它們對于微服務部署而言是至關重要的。

Spring Cloud基于Spring Boot建構,其中Spring Boot包含了使用最小配置的内嵌tomcat伺服器。

如下是在AWS雲上使用微服務的分布式應用的架構圖。

<a href="http://dockerone.com/uploads/article/20170112/b9b435e9dd377b6f5f4a02b38586bf26.png" target="_blank"></a>

上述圖例中,我們有3個不同的微服務,其中主微服務使用REST用戶端與微服務A和微服務B通信。微服務A運作于2個容器中,微服務B運作于同一執行個體的2個容器中。主微服務暴露給用戶端,會通過服務用戶端與任何微服務A或微服務B的執行個體互動,這個用戶端是一款負載均衡器。這将會使得負載均衡不僅存在于執行個體級别,更存在于同一執行個體的服務級别。這就是所謂的服務級負載均衡。當向一個服務發送請求時,用戶端服務會通過查詢Eureka服務注冊和服務發現取得服務執行個體的位址。

Spring Cloud已經支援使用Eureka作為服務注冊,并且Eureka服務注冊可以通過添加<code>@EnableEurekaServer</code>标注開啟。

用于服務注冊的application.yml:

任何微服務都可以通過添加<code>@EnableDiscoverClient</code>标注,将Eureka服務注冊的位址以及端口放置于application.yml或application.properties檔案,以将自己注冊到Eureka伺服器。

Spring Cloud提供多種程序間通訊方式,其中包括外部用戶端和Rest模闆。外部用戶端是十分靈巧、幹淨以及易于實作的。可以通過添加<code>@EnableFeignClient</code>标注來開啟外部用戶端。

用戶端應用必須建立一個接口,該接口使用<code>@FeignClient</code>标注,需配合服務ID,内部的方法使用<code>@RequestMapping</code>标注。

我們可以通過建立一個新的類來調用這些接口方法,ServiceClientBean.java。

通過在<code>@EnableFeignClients</code>中添加<code>basePackageClasses</code>屬性值,所有<code>@FeignClient</code>類都能以Spring bean的形式注冊。

開發者可以在用戶端和伺服器之間共享相同的接口定義,但這會增加用戶端和伺服器之間的耦合度。

外部用戶端自動支援使用Ribbon的負載均衡。Ribbon是用戶端的負載均衡器,其對HTTP和TCP請求提供了大量控制支援。我們可以使用外部屬性<code>client.ribbon.*</code>來配置Ribbon用戶端。

在ServiceClientBean.java中,我們添加了一個<code>@HystrixCommand</code>标注來處理部分失敗。此指令會告訴Spring,該方法容易出錯。Spring Cloud庫包裝了這些方法以通過斷路器來實施容錯和延遲容忍。典型的Hystrix指令後面跟着復原方法。至于故障,Hystrix會自動啟用復原方法提醒,并且将流量引導至復原方法。

如果微服務A無法在限定時間内發送響應或者是幹脆直接宕掉,那麼Hystrix将會調用復原方法來擷取預設的響應。

我們可以通過添加Hystrix儀表盤應用來檢視Hystrix統計和監控。

這裡還有一個稱為Zuul代理的元件,能夠充當服務網關。上文的架構圖例中并沒有提及。服務網關内部調用多個微服務,并将來自這些微服務的結果聚合,并傳回給用戶端服務。

Zuul代理内部使用Eureka伺服器作為服務發現,使用Ribbon作為服務執行個體間的負載均衡。

分布式應用需要某種中心化日志架構,這可以通過ELK工具棧來簡單實作。

<b>原文釋出時間為:</b>2017-01-12

<b>本文作者:</b>孫科

<b>本文來自雲栖社群合作夥伴Dockerone.io,了解相關資訊可以關注Dockerone.io。</b>

<b></b>

<b>原文标題:</b><b>基于微服務的分布式應用開發</b>