服務註冊中心之Eureka使用

我若安好,便是晴天發表於2021-10-11

一、Eureka基礎

  Eureka是Netflix開發的服務發現框架,本身是一個基於REST的服務,主要用於定位執行在AWS域中的中間層服務,以達到負載均衡和中間層服務故障轉移的目的。SpringCloud將它整合在其子專案spring-cloud-netflix中,以實現SpringCloud的服務發現功能。Eureka包含兩個元件:Eureka Server和Eureka Client。在Eureka Client應用啟動後,將會向Eureka Server傳送心跳,預設週期為30秒,如果Eureka Server在多個心跳週期內沒有接收到某個節點的心跳,Eureka Server將會從服務登錄檔中把這個服務節點移除(預設90秒)。Eureka Server之間通過複製的方式完成資料的同步,Eureka還提供了客戶端快取機制,即使所有的Eureka Server都掛掉,客戶端依然可以利用快取中的資訊消費其他服務的API。綜上,Eureka通過心跳檢查、客戶端快取等機制,確保了系統的高可用性、靈活性和可伸縮性。

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

  Eureka Client是一個java客戶端,用於簡化與Eureka Server的互動,客戶端同時也就是一個內建的、使用輪詢(round-robin)負載演算法的負載均衡器。

  服務治理產生的原因?

   傳統的rpc遠端呼叫框架中,要進行每個服務之間的依賴管理是比較複雜的,所以需要服務治理來管理服務之間的依賴關係,可以實現服務呼叫、負載均衡、容錯等,實現服務的發現與註冊。springCloud封裝了Netflix公司的Eureka模組來實現服務治理。

  什麼是服務註冊與發現?

   Eureka採用了cs客戶-服務設計模式,Eureka Server作為服務註冊功能的伺服器,它是服務註冊中心。而系統中的其他服務,則使用Eureka的客戶端連線到Eureka Server並維持心跳。這樣系統的維護人員就可以通過Eureka Server來監控系統中各個服務模組的執行狀況。當服務啟動的時候會把自己的伺服器資訊註冊到Eureka Server註冊中心,這就是服務註冊。當呼叫方用服務別名去獲取和查詢服務資訊這就是服務發現。註冊中心擁有管理服務之間依賴關係的能力,這就是服務治理的概念。在任何rpc遠端呼叫框架中,都會有一個註冊中心用於存放微服務模組相關的地址資訊(服務在註冊中心是以鍵值對形式存在的,key為服務名,value為呼叫地址),當服務呼叫者需要呼叫某個服務時,就用該服務的別名去註冊中心查詢,獲取對應的呼叫地址(獲取後可能會快取該地址,會根據配置定時更新地址),獲得呼叫地址後底層利用httpclient技術實現遠端呼叫。

  Eureka的架構模式:Eureka服務註冊中心可以有多個形成叢集,服務提供者也可以有多個形成叢集,而消費者可以只有一個,他們的架構關係如下圖。

、單機Eureka-Server註冊中心構建

  按照Maven專案模組的建立方式,依次進行建立模組、修改POM、編寫yml配置檔案、編寫主啟動類的順序完成服務模組的編寫。編寫完成啟動該模組後訪問ip+port即可顯示一個服務監控介面,如下圖。

  編寫主啟動類時,在啟動類上加入@EnableEurekaServer註解,以表示該模組是服務註冊中心。

  編寫POM時,引入Eureka-server包和圖形監控包,如下所示:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupid>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

  編寫yml檔案時,在resources資料夾下建立application.yml檔案,並寫入如下程式碼:

server:
port:8765
eureka:
  client:
    register-with-eureka: false   #false表示不向服務註冊中心註冊自己
    fetch-registry: false #false表示自己就是註冊中心,不需要去檢索服務
    service-url:   #與Eureka-server互動的地址查詢服務和註冊服務,都需要使用這個地址
      default-zone: http://eurekaServer:8765/eureka/eureka
  instance:
    hostname: main-service  #eureka服務端的例項名稱

三、Eureka將服務模組註冊到註冊中心成為服務提供者

  同樣按照Maven專案模組的建立方式,依次進行建立模組、修改POM、編寫yml配置檔案、編寫主啟動類的順序完成服務模組的編寫。

  編寫主啟動類時,在啟動類上加入@EnableEurekaClient註解,以表示該模組是服務提供者。

  編寫POM時,引入Eureka-client包,如下所示:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

  編寫yml檔案時,在resources資料夾下建立application.yml檔案,並寫入如下程式碼server:

   port:8088
spring:
 application:
  name:service-name  #表示服務模組的名稱,當服務註冊到註冊中心後,可以在監控介面顯示該名稱,以定位該服務。
eureka:
  client:
    register-with-eureka: true   #true表示向服務註冊中心註冊自己
    fetch-registry: true #true表示檢索服務,單節點可以不設定,叢集節點必須設定為true才能配合ribbon使用負載均衡
    service-url:   #這是服務註冊中心地址,表示該服務要註冊到哪一個註冊中心
      default-zone: http://eurekaServer:8765/eureka/eureka
  instance:
instance-id:servicename #服務名稱
   prefer-ip-address:true #訪問路徑顯示ip地址
lease-renewal-interva1-in-seconds: 20 #EurekaClient向服務端傳送心跳的時間間隔,單位為秒(預設是30秒)
lease-expiration-duration-in-seconds: 60   #EurekaServer在收到最後一次心跳後等待時間上限,單位為秒(預設是90秒),超時將剔除服務

  當該服務啟動後,可以在註冊中心監控介面檢視到該服務的資訊,如圖所示:

、Eureka註冊中心負載均衡叢集理論

  1.註冊中心叢集:多個註冊中心相互註冊,形成相互守望,對外暴露出這些註冊中心地址,使用負載均衡服務來訪問這些地址。

  2.服務提供者叢集:註冊中心可以叢集,服務提供者也可以叢集,實現服務提供者叢集需完成以下兩件事情:

    a.當服務提供者叢集以後,就不能使用埠的形勢(http://ip:port)來呼叫服務提供者,呼叫消費者需使用微服務名稱來呼叫提供者(http://cloud-servername),原因是叢集狀態下服務提供者埠不止一個。

    b.消費者通過微服務名稱來呼叫提供者時,因為叢集會有多個相同的微服務名稱,會出現呼叫不明確的情況而報錯,因此需要賦予RestTemplate負載均衡能力,具體實現是在消費者的ApplicationContextConfig配置檔案的getRestTemplet()下增加@LoadBalanced註解。(RestTemplate 是從 Spring3.0 開始支援的一個 HTTP 請求工具,它提供了常見的REST請求方案的模版,例如 GET 請求、POST 請求、PUT 請求、DELETE 請求以及一些通用的請求執行方法 exchange 以及 execute。)

  3.服務模組需要同時註冊到每個叢集的註冊中心:其註冊方式為在yml配置檔案中的defaultzone下使用","逗號來分割這些註冊中心地址。

 五、服務發現Discovery

  微服務自身要向外提供服務功能,就需要向外部提供微服務的資訊,服務本身可以向外暴露一個discovery()方法,消費者可以通過呼叫該方法獲得服務的說明資訊。在eureka元件中,通過DiscoveryClient類來實現,該類可以獲取已經在註冊中心註冊成功的所有微服務的資訊。微服務要向外提供資訊,需要在主啟動類上增加@EnableDiscoveryClient註解,同時需要給DiscoveryClient類增加註解@resource註解。

  

 六、Eureka的自我保護機制

  保護模式主要用於一組客戶端和EurekaServer之間存在網路分割槽時的保護,EurekaServer將嘗試保護其登錄檔中的資訊,不再刪除服務登錄檔中的資料,也不會登出任何微服務。如果在EurekaServer首頁看到如下提示,則表示進入了保護模式。

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE。

  通俗的說,就是指某一時刻某一個微服務不可用了,Eureka不會立即清理,依舊會對該服務的資訊進行儲存。這是CAP理論中的AP理論。為什麼會產生自我保護機制?這是為了防止Eureka可以正常執行,但與EurekaServer之間網路不通時造成誤刪。

  什麼是自我保護模式?預設情況下,如果EurekaServer在一定時間內沒有收到某服務的心跳,EurekaServer會將其登出(預設90秒),但是當EurekaServer與服務模組之間網路存在延時、卡頓、擁擠時,他們之間無法正常傳送心跳,此時微服務本身是健康的,不應該被登出。Eureka就通過"自我保護模式"來解決,自我保護模式的思想是當檢測到短時間內偶爾沒有收到心跳時(可能發生了網路分割槽故障),不會立即刪除微服務。

  如何禁止自我保護?在EurekaServer的application.yml配置檔案中server節點下增加如下配置:

server:               
     enable-self-preservation: false  #關閉自我保護機制
     eviction-interval-timer-in-ms: 2000  #心跳間隔時間

  關閉自我保護模式後,重新整理註冊中心頁面主頁,則會出現THE SELF PRESERVATION MODE IS TURNED FFNCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.提示。

  七、Eureka停止更新的說明

  Netflix官網公告了Eureka已經停止更新,進入維護模式,除非已經在專案中使用該元件,新專案建議使用其他替代元件,比如Zookeeper、Consul、Nacos等。

 

 

 

 

 

  

相關文章