1. 程式人生 > >那些年,想和你一起認識的SpringCloud Eureka

那些年,想和你一起認識的SpringCloud Eureka

  前幾天魯班LB跟我說:你玩把遊戲都要半個鍾啦,為何不用這時間來看看書,如果漲工資還可以幫我買個面板。

  面對如此合理的這需求,但我不以為然,事實上並不是我不想學習,而是 ↓ 

  

  實力不允許呀~

  直到有一天,突然被叫到會議室,心裡疙瘩一下,這難道?專案出嚴重Bug了,冷靜的我思索片刻後,很快就會否定了這種想法,結果巴拉巴拉2小時後,結論竟然是說:“現在我們這個專案要求重構,需用使用微服務架構,所以不瞭解相關技術的同事請利用這段時間學習複習一下,下個月要開始進入開發階段。

  呵呵,會議上,總是有人把微服務吹的很厲害似的,我笑而不語,於是

  

  一週後

  

  

   以下是我的筆記,我一般是帶著問題去學習,有了需求,或者說是好奇心,因為這樣學習的效率會更高

  當看到我們架構中有Eureka,我的第一個問題自然就是:做微服務為什麼要使用Eureka,或者Eureka能夠幫助我們解決什麼樣的問題?

  對於微服務的概念有經驗的開發人員的一般都聽說過吧,無非就是把大應用拆分為小應用,然後處理好服務的相互通訊即可,但是如果光啟動微服務時,不啟動eureka,其他微服務也是可以通過Nginx反向代理,用rest的方式從不同服務後臺獲取到資料(HTTP直懟),那多個eureka服務豈不是多此一舉嗎?細想一下其實並不是的,我覺得原因有如下:

  其一:

  如果後端微服務之間,有互相通訊,那麼在負載均衡時,相同的服務肯定會啟動多個,而且使用不同的埠,這個時候,服務之間就可以通過註冊在eureka中的名稱來找到對方,而不是根據IP+埠號去找對方。反之如果後端微服務之間相互通訊,都要知道具體的IP和埠,那開發起來十分麻煩,而IP地址也並不是固定不變的,除非使用域名封裝,所以無論是測試還是開發還是上線都存在問題。

  其二:

  Eureka註冊中心的作用很大的程度是作用於服務發現和服務心跳,在多個註冊中心的時候,依賴於zuul的負載均衡,保證異常的服務停止,正常的服務載入,保證服務的穩定性。

  新手可能不理解這說的是什麼意思,沒關係,請往下看,首先我們先說說什麼是SpringCloud

  SpringCloud是一系列框架的有序集合。它利用SpringBoot的開發便利性巧妙地簡化了分散式系統基礎設施的開發,如服務發現註冊、配置中心、訊息匯流排、負載均衡、 熔斷器、資料監控等,都可以用SpringBoot的開發風格做到一鍵啟動和部署。是一套簡單易懂、易部署和易維護的分散式系統開發工具包。

  主要組成如下:

  •   服務發現——Netflix Eureka                      服務呼叫——Netflix Feign
  •   熔斷器——Netflix Hystrix                          服務閘道器——Netflix Zuul
  •   分散式配置——Spring Cloud Config         訊息匯流排 —— Spring Cloud Bus

  

  本文主要介紹Eureka註冊中心

  組成原理:

  Eureka包含兩個元件: Eureka Server和Eureka Client:

  Eureka Server提供服務註冊服務,各個Client節點啟動後,會在Eureka Server中進行註冊,這樣EurekaServer中的服務登錄檔中將會儲存所有可用服務節點的資訊,服務節點的資訊可以在介面中直觀的看到。

  Eureka Client是一個java客戶端,用於簡化與Eureka Server的互動,客戶端有一個內建的、使用輪詢(round-robin)負載演算法的負載均衡器。在應用啟動後,將會向Eureka Server傳送心跳,預設週期為30秒,如果Eureka Server在多個心跳週期內沒有接收到某個節點的心跳,Eureka Server將會從服務登錄檔中把這個服務節點移除(預設90 秒)。如果Eureka Server做了叢集,Eureka Server之間通過複製的方式完成資料的同步,同時Eureka還提供了客戶端快取機制,即使所有的Eureka Server都掛掉,客戶端依然可以利用快取中的資訊消費其他服務的API。

  綜上,Eureka能夠通過心跳檢查、客戶端快取等機制,確保了系統的高可用性。

 

  問題:同為註冊中心,Eureka要比Zookeeper好在哪,或者說為什麼Cloud為什麼不整合Zookeeper,在CAP理論中說道,一個分散式系統不可能同時滿足C(一致性)、A(可用性)和P(分割槽容錯性)。由於分割槽容錯性在是分散式系統中必須要保證的,因此我們只能在A和C之間進行權衡。我們從需求出發考慮,當向註冊中心查詢服務列表時,我們可以容忍註冊中心返回的是幾分鐘以前的註冊資訊,但不能接受服務直接down掉不可用。也就是說,對於服務註冊功能對可用性的要求要高於一致性。

  Eureka不會出現這種問題,Zookeeper則會出現這樣一種情況,當master節點因為網路故障與其他節點失去聯絡時,剩餘節點會重新進行leader選舉。選舉leader的時間太長,30 ~ 120s, 且選舉期間整個zk叢集都是不可用的,這就導致在選舉期間註冊服務癱瘓。在雲部署的環境下,因網路問題使得zk叢集失去master節點是較大概率會發生的事,雖然服務能夠最終恢復,但是漫長的選舉時間導致的註冊長期不可用是不能容忍的。

  而在此Zookeeper保證的是CP, 而Eureka則是AP,顯然Eureka更加合適。

  但在預設配置中,Eureka Server在預設90s沒有得到客戶端的心跳,則登出該例項,但是往往因為微服務跨程序呼叫,網路通訊往往會面臨著各種問題,比如微服務狀態正常,但是因為網路分割槽故障時,Eureka Server登出服務例項則會讓大部分微服務不可用,這很危險,因為服務明明沒有問題。為了解決這個問題,Eureka 有自我保護機制,通過在Eureka Server配置引數,可啟動保護機制它的工作原理是:當Eureka Server節點在短時間內丟失過多的客戶端時(可能傳送了網路故障),那麼這個節點將進入自我保護模式,不再登出任何微服務,當網路故障回覆後,該節點會自動退出自我保護模式。

  實戰:

  Eureka服務端開發(非常簡單的3步完成)

  1.從官網下載腳手架專案https://start.spring.io/

  2.修改一下配置檔案

  3.啟動,本質上也是一個SpringBoot專案

  

 

   把下載好的Demo匯入編譯器,開啟application.properties或 .yml配置檔案

  

#配置埠
server:
    port: 8761  #服務埠
#配置服務名稱
spring:
  application:
    name: service-name #是否將自己註冊到Eureka服務中,本身就是服務端,所以無需註冊
#是否從Eureka中獲取註冊資訊
#客戶端和服務端互動地址 eureka: client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://127.0.0.1:${server.port}/eureka/

  配置啟動類

@SpringBootApplication
//加入註解,宣告為服務端 @EnableEurekaServer public class EurekaServer { public static void main(String[] args) { SpringApplication.run(EurekaServer.class, args); } }

 

  上圖為Eureka服務端啟動成功,視覺化介面,Application表示當前並無客戶端使用者註冊進來,這裡說的客戶端就是我們開發的微服務應用

 

  Eureka客戶端開發(其實就是我們真正業務微服務應用)

  1.從官網下載腳手架專案https://start.spring.io/

  2.修改一下配置檔案

 

#配置埠
server:
  port:1111
#配置服務名稱
spring:
  application:
    name : client-name
#配置伺服器路徑
eureka: client: service‐url: defaultZone: http://localhost:8761/eureka instance: prefer‐ip‐address: true

  啟動類配置

//加入註解,宣告為微服務客戶端,專案啟動後自動向服務端註冊
@EnableDiscoveryClient @SpringBootApplication public class ServiceProviderApplication { public static void main(String[] args) { SpringApplication.run(ServiceProviderApplication.class, args); } }

  啟動後就能在服務端視覺化介面看見客戶端的註冊資訊,我們現在就將所有的微服務都註冊到Eureka中,這樣所有的微服務之間都可以互相呼叫,服務的呼叫將在下一篇文章詳細講解

   

  但是有時候會出現下面的文字

  

  說明Eureka已經進入了保護模式:

  Eureka Server在執行期間,會統計心跳失敗的比例在15分鐘之內是否低於85%,如果出現低於的情況(在生產環境上通常是由於網路不穩定導致),Eureka Server會將當前的例項註冊資訊保護起來,同時提示這個警告。保護模式主要用於一組客戶端和Eureka Server之間存在網路分割槽場景下的保護。一旦進入保 護模式,Eureka Server將會嘗試保護其服務登錄檔中的資訊,不會登出任何微服務。

  

  關於Eureka Server叢集的介紹

  Eureka註冊中心只部署在一臺機器上,一旦出現問題,會導致整個服務呼叫系統的崩潰,針對這種情況,我們需要部署兩臺Eureka註冊中心,彼此相互註冊,組成一個高可用的的Eureka叢集。這樣一來,每臺伺服器都包含著對方的服務註冊資訊,相當於雙機熱備,同時,服務提供者只需向其中的一個註冊服務。

   在生產環境中,一般是把兩個相互註冊的伺服器安裝在兩臺伺服器上,現在我們在一臺機器上模擬雙伺服器的場景,具體的實現步驟如下:

  到C:\WINDOWS\system32\drivers\etc目錄裡,找到hosts檔案,在其中加入兩個機器名(其實都是指向本機),程式碼如下。修改後,需要重啟機器。

          127.0.0.1      erueka-server

          127.0.0.1      erueka-server2

  配置如下

Eureka service

server:
        port: 8761 #埠號
spring:
  application:
    name: eureka-server #應用名
eureka: instance: hostname: hostname1 client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://hostname1:8761/eureka/,http://hostname2:8762/eureka/

Eureka service2

server:
        port: 8762 #埠號
spring:
  application:
    name: eureka-server2 #應用名

eureka:
        instance:
              hostname: hostname2
         client:
            register-with-eureka: true
            fetch-registry: true
            service-url:
                defaultZone: http://hostname1:8761/eureka/,http://hostname2:8762/eureka/  

  這樣下來,就算有一臺機器宕機了,然後可讓服務正常工作。