SpringCloud——(二)組件:eureka

Spring-Cloud項目的搭建 


因爲spring-cloud是基於spring-boot項目來的,所以我們項目得是一個spring-boot項目,這裏要注意的一個點是spring-cloud的版本與spring-boot的版本要對應下圖:

參考:https://spring.io/projects/spring-cloud-alibaba 或 https://spring.io/projects/spring-cloud

SpringCloud常用組件 

服務發現——Netflix Eureka

客服端負載均衡——Netflix Ribbon

斷路器——Netflix Hystrix

服務網關——Netflix Zuul

分佈式配置——Spring Cloud Config 

本文使用版本

SpringBoot :2.2.6

SpringCloud: Hoxton.SR3

<!--SpringBoot-->
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
</dependencies>

<!--SpringCloud-->
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

一、Spring-Cloud-Netflix組件:Eureka

作用:實現服務治理(服務註冊與發現)

簡介:

Eureka是Netflix(https://spring.io/projects/spring-cloud-netflix)的子模塊之一,也是一個核心的模塊,Eureka裏有2個組件:

1、EurekaServer 用作服務註冊中心。支持集羣部署。

這個是用於定位服務以實現中間層服務器的負載平衡和故障轉移

2、EurekaClient 是一個java客戶端,用來處理服務註冊與發現。

用於與Server交互的,可以使得交互變得非常簡單:只需要通過服務標識符即可  拿到服務。

與spring-cloud的關係:

Spring Cloud 封裝了 Netflix 公司開發的 Eureka 模塊來實現服務註冊和發現(可以對比Zookeeper)。

Eureka 採用了 C-S 的設計架構。Eureka Server 作爲服務註冊功能的服務器,它是服務註冊中心。

而系統中的其他微服務,使用 Eureka 的客戶端連接到 Eureka Server並維持心跳連接。這樣系統的維護人員就可以通過 Eureka Server 來監控系統中各個微服務是否正常運行。(在應用啓動時,Eureka客戶端向服務端註冊自己的服務信息,同時將服務端的服務信息緩存到本地。客戶端會和服務端週期性的進行心跳交互,以更新服務租約和服務信息。)

SpringCloud 的一些其他模塊(比如Zuul)就可以通過 Eureka Server 來發現系統中的其他微服務,並執行相關的邏輯。

角色關係圖:

二、搭建一個簡單的Eureak (單機版)

1、Eureka Server加入依賴 :

    <dependencies>      
        <!--服務端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

EurekaServer服務端配置:application.yml

例如: 

server:
  port: 3000
eureka:
  server:
    enable-self-preservation: false  #關閉自我保護機制
    eviction-interval-timer-in-ms: 4000 #設置清理間隔(單位:毫秒 默認是60*1000)
  instance:
    hostname: localhost


  client:
    registerWithEureka: false #表示是否註冊自身到eureka服務器,因爲當前這個應用就是eureka服務器,沒必要註冊自身
    fetchRegistry: false  #不需要從服務端獲取註冊信息(因爲在這裏自己就是服務端,而且已經禁用自己註冊了)
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka

在spring-boot啓動項目上 加入註解:@EnableEurekaServer 就可以啓動項目了

如果看見這個圖片,那麼說明你就搭建好了:

注意:這個警告只是說你把他的自我保護機制關閉了。(因爲.yml文件中設置了enable-self-preservation: false)

打開自我保護機制:如果某臺機器宕機,Eureka會認爲是自己問題。

2、EurekaClient加入依賴 :

    <dependencies>
        <!--客戶端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>     
    </dependencies>

EurekaClient客戶端配置:application.yml

例如:

server:
  port: 6000
eureka:
  client:
    serviceUrl:
        defaultZone: http://localhost:3000/eureka/  #eureka服務端提供的註冊地址 參考服務端配置的這個路徑
  instance:
  	
    instance-id: power-1 #此實例註冊到eureka服務端的唯一的實例ID 
    prefer-ip-address: true #是否顯示IP地址
    leaseRenewalIntervalInSeconds: 10 #eureka客戶需要多長時間發送心跳給eureka服務器,表明它仍然活着,默認爲30 秒 (與下面配置的單位都是秒)
    leaseExpirationDurationInSeconds: 30 #Eureka服務器在接收到實例的最後一次發出的心跳後,需要等待多久纔可以將此實例刪除,默認爲90秒

spring:
  application:
    name: server-power #此實例註冊到eureka服務端的name 

在客戶端的spring-boot啓動項目上 加入註解:@EnableEurekaClient 就可以啓動項目了

看效果圖:

如果配置多個EurekaClient,那麼如下圖:

三、Eureka集羣

Eureka集羣原理

服務啓動後向Eureka註冊,Eureka Server會將註冊信息向其他Eureka Server進行同步,當服務消費者要調用服務提供者,則向服務註冊中心獲取服務提供者地址,然後會將服務提供者地址緩存在本地,下次再調用時,則直接從本地緩存中取,完成一次調用。

此處單臺機器模擬集羣:修改文件【C:\Windows\System32\drivers\etc 中的 hosts】增加 域名的映射

注意:集羣配置與單體不同的點在於 原來是把服務註冊到自己身上,而現在是註冊到其它服務身上。Why?

Eureka的server會把自己的註冊信息與其他的server同步,所以這裏我們不需要註冊到自己身上,因爲另外兩臺服務器會配置本臺服務器。

1、配置服務端 EurekServer

假設我們有3個Eureka Server 模塊如圖: 

配置時注意:是註冊到其他的服務上 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

配置服務端子模塊 eureka3000:application.yml

server:
  port: 3000
eureka:
  server:
    enable-self-preservation: false  #關閉自我保護機制
    eviction-interval-timer-in-ms: 4000 #設置清理間隔(單位:毫秒 默認是60*1000)
  instance:
    hostname: eureka3000.com


  client:
#    registerWithEureka: false #表示是否註冊自身到eureka服務器,因爲當前這個應用就是eureka服務器,沒必要註冊自身
#    fetchRegistry: false  #不需要從服務端獲取註冊信息(因爲在這裏自己就是服務端,而且已經禁用自己註冊了)
    serviceUrl:
      defaultZone: http://eureka3001.com:3001/eureka,http://eureka3002.com:3002/eureka

配置服務端子模塊 eureka3001:application.yml

server:
  port: 3001
eureka:
  server:
    enable-self-preservation: false  #關閉自我保護機制
    eviction-interval-timer-in-ms: 4000 #設置清理間隔(單位:毫秒 默認是60*1000)
  instance:
    hostname: eureka3001.com


  client:
#    registerWithEureka: false #表示是否註冊自身到eureka服務器,因爲當前這個應用就是eureka服務器,沒必要註冊自身
#    fetchRegistry: false  #不需要從服務端獲取註冊信息(因爲在這裏自己就是服務端,而且已經禁用自己註冊了)
    serviceUrl:
      defaultZone: http://eureka3000.com:3000/eureka,http://eureka3002.com:3002/eureka

配置服務端子模塊 eureka3002:application.yml

server:
  port: 3002
eureka:
  server:
    enable-self-preservation: false  #關閉自我保護機制
    eviction-interval-timer-in-ms: 4000 #設置清理間隔(單位:毫秒 默認是60*1000)
  instance:
    hostname: eureka3002.com


  client:
#    registerWithEureka: false #表示是否註冊自身到eureka服務器,因爲當前這個應用就是eureka服務器,沒必要註冊自身
#    fetchRegistry: false  #不需要從服務端獲取註冊信息(因爲在這裏自己就是服務端,而且已經禁用自己註冊了)
    serviceUrl:
      defaultZone: http://eureka3000.com:3000/eureka,http://eureka3001.com:3001/eureka

配置完畢後,全部啓動查看:

http://eureka3000.com:3000/

 

http://eureka3001.com:3001/

 

http://eureka3002.com:3002/

 

2、配置客戶端 EurekClient

配置客戶端子模塊 user:application.yml

server:
  port: 5000
eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka3000.com:3000/eureka/,http://eureka3001.com:3001/eureka/,http://eureka3002.com:3002/eureka/  #eureka服務端提供的註冊地址 參考服務端配置的這個路徑
  instance:
    instance-id: user-1 #此實例註冊到eureka服務端的唯一的實例ID
    prefer-ip-address: true #是否顯示IP地址
    leaseRenewalIntervalInSeconds: 10 #eureka客戶需要多長時間發送心跳給eureka服務器,表明它仍然活着,默認爲30 秒 (與下面配置的單位都是秒)
    leaseExpirationDurationInSeconds: 30 #Eureka服務器在接收到實例的最後一次發出的心跳後,需要等待多久纔可以將此實例刪除,默認爲90秒

spring:
  application:
    name: client-user #此實例註冊到eureka服務端的name

注意:原來是註冊到一個地址上面,現在是要寫三個eureka註冊地址,但是不是代表他會註冊三次,因爲我們eureka server的註冊信息是同步的,這裏只需要註冊一次就可以了,但是爲什麼要寫三個地址呢?????????因爲這樣就可以做到高可用的配置:比如有3臺服務器,突然宕機了一臺, 但是其他2臺還健在,依然可以註冊我們的服務,換句話來講, 只要有一臺服務還建在,那麼就可以註冊服務。

總結:服務隨便註冊到哪個eureka server上,其他的eureka server上都有該服務的註冊信息。

3、 測試

先啓動EurekaServer中的一個服務:比如【eureka3000】 ,再啓動客戶端 user

 

接着啓動EurekaServer中的一個服務:比如【eureka3001】


四、Eureka對比Zookeeper:

Zookeeper

Eureka

 Zookeeper在設計的時候遵循的是CP原則,即一致性。 Eureka在設計的時候遵循的是AP原則,即可用性。

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

Eureka各個節點(服務)是平等的, 沒有主從之分,幾個節點down掉不會影響正常工作,剩餘的節點(服務) 依然可以提供註冊與查詢服務,而Eureka的客戶端在向某個Eureka註冊或發現連接失敗,則會自動切換到其他節點,也就是說,只要有一臺Eureka還在,就能註冊可用(保證可用性), 只不過查詢到的信息不是最新的(不保證強一致);

除此之外,Eureka還有自我保護機制,如果在15分鐘內超過85%節點都沒有正常心跳,那麼eureka就認爲客戶端與註冊中心出現了網絡故障,此時會出現以下情況:

1:Eureka 不再從註冊列表中移除因爲長時間沒有收到心跳而過期的服務。

2:Eureka 仍然能夠接收新服務的註冊和查詢請求,但是不會被同步到其它節點上(即保證當前節點可用)

3:當網絡穩定後,當前實例新的註冊信息會被同步到其它節點中

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章