Spring Cloud(一):服務注冊中心Eureka


Spring Cloud 基於 Netflix 的幾個開源項目進行了封裝,提供包括服務注冊與發現(Eureka),智能路由(Zuul),熔斷器(Hystrix),客戶端負載均衡(Ribbon)等在內的核心組件。

在微服務系統中,服務少則十幾、幾十個,多則上百、幾百個(據悉 Netflix 的雲平台上運行了500多個微服務),這些微服務通過相互調用來為用戶提供功能。那么一個服務調用另一個服務是如何進行的,如何定位到另一個服務的地址?代碼中寫死,還是配置文件中配置?顯然對於服務數量較多的系統,這兩種方式先不說后續維護,光寫起來就很痛苦。於是,對於微服務架構來說,服務的自動注冊與發現就成為非常核心的功能,Eureka就是來負責實現這個功能的。

本系列文章與示例均基於最新的Spring Cloud Hoxton版編寫。

Eureka

Eureka是一個基於REST的服務,包括Eureka Server與Eureka Client兩個端。Eureka Server作為服務注冊中心接受Eureka Client的注冊及獲取其它服務的地址信息。基本架構如下圖所示:

其中

  • Eureka Server: 作為服務注冊中心,提供服務注冊與發現功能接口

  • Service Provider: 服務提供者,將自身服務注冊到服務注冊中心,供其它服務消費者發現與調用

  • Service Consumer: 服務消費者,從服務注冊中心發現服務,並通過一些負載均衡客戶端來調用(比如Ribbon或Feign)

     

很多時候同一個應用可能既是服務提供者,也是服務消費者——自己作為服務方,為其它服務提供接口,同時也調用其它服務的接口來完成自身的業務邏輯。


Eureka Server

Eureka Server的搭建非常簡單,其部署可分為單實例部署與多實例集群部署,一般開發測試環境可以使用單實例部署,但生產環境出於高可用要求,可進行多實例集群部署。

 

1. 在pom.xml中添加依賴

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

為了方便版本引入,可以在pom中添加依賴管理,這樣spring cloud相關的starter依賴就不需要指定版本了(如上省略了version)

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

 

2. 在啟動類上添加注解 @EnableEurekaServer

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

 

3. 在application.yml 或 application.properties配置文件中添加配置(個人比較傾向於yml,兩者區別可自行百度) 

spring:
  application:
    name: spring-cloud-eureka
  profiles:
    active: single

server:
  port: 8761

---
spring:
  profiles: single
eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      
---
spring:
  profiles: peer1
server:
  port: 8761
eureka:
  instance:
    hostname: peer1
  client:
    serviceUrl:
      defaultZone: http://peer2:8762/eureka/,http://peer3:8763/eureka/
---
spring:
  profiles: peer2
server:
  port: 8762
eureka:
  instance:
    hostname: peer2
  client:
    serviceUrl:
      defaultZone: http://peer1:8761/eureka/,http://peer3:8763/eureka/
---
spring:
  profiles: peer3
server:
  port: 8763
eureka:
  instance:
    hostname: peer3
  client:
    serviceUrl:
      defaultZone: http://peer1:8761/eureka/,http://peer2:8762/eureka/

 在該配置文件中,實際上是定義了兩種模式,其中默認的profile single是單實例模式, peer1, peer2, peer3組成多實例模式。

  • eureka.client.registerWithEureka:表示是否將自身注冊到Eureka Server,默認為true,單實例模式下一般設置為false,否則會在啟動時報連接不到服務器的錯誤
  • eureka.client.fetchRegistry:表示是否從Eureka Server獲取注冊服務列表,默認為true,同樣在單實例模式下設置為false

  • eureka.client.serviceUrl.defaultZone:Eureka Server的地址,多實例模式下多個地址以“,”隔開,多個實例之間只要有一條路線連通,則總會將注冊信息進行同步

 

4. 啟動

對於單實例模式,如果按如上配置,則直接啟動程序即可。啟動完成后,訪問 http://localhost:8761,即可查看Eureka Server的相關信息,如

 上圖所示,當前沒有Eureka Server的副本也沒有任何服務注冊。

 

對於多實例集群模式,則需要根據不同的profile啟動多個實例,

mvn clean package
cd target
java -jar springcloud-eureka-1.0-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar springcloud-eureka-1.0-SNAPSHOT.jar --spring.profiles.active=peer2
java -jar springcloud-eureka-1.0-SNAPSHOT.jar --spring.profiles.active=peer3

 

啟動完成后,打開 http://localhost:8761, 可以看到Eureka Server已經存在副本與注冊的服務了(Eureka將自身作為一個服務完成了注冊)

 

上述操作如果是在單機進行,則需要在hosts文件中添加映射,linux下是/etc/hosts,windows10 下是C:\Windows\System32\drivers\etc\hosts,

127.0.0.1 peer1
127.0.0.1 peer2
127.0.0.1 peer3

 

Eureka Client

Eureka Client一般集成在各個微服務中,集成也非常簡單。

1. pom.xml中添加依賴

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

 

2. application.yml配置文件中添加配置

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
    instance-id: ${spring.application.name}:${random.uuid}

 

如果是多實例集群模式,則 eureka.client.serviceUrl.defaultZone 可以配置多個地址,“,”號分隔。

  • eureka.client.*:發現服務的配置參數

  • eureka.instance.*:注冊服務的配置參數, 如上 eureka.instance.prefer-ip-address 設置為true表示服務注冊時使用IP,而不是hostname; eureka.instance.instance-id 配置服務實例的ID,默認為 ${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}}

添加了依賴就能集成Eureka Client,主類上添加 @EnableDiscoveryClient 注解不是必須。

 

啟動程序后,進入Eureka Server頁面即可看到注冊的服務

 

一些知識點(建議掌握)

  1. Eureka Client在注冊服務時,提供包括hostname,IP地址, port, health indicator url,status page, home page 等在內的meta-data,其它客戶端可通過這些信息來直接與服務進行交互,我們也可以通過 eureka.instance.metadataMap 來添加自定義的meta-data,供客戶端訪問。

     

  2. Eureka Server通過接收Eureka Client的心跳消息來判斷服務實例是否存活,如果某一個實例的心跳在特定時間(可配置)內沒收到,則將其從注冊表中移除。心跳默認間隔為30s,一個服務被其它客戶端發現,可能需要經過3次心跳,這也是有時候服務注冊比較慢的原因。可通過eureka.instance.leaseRenewalIntervalInSeconds配置,但生產環境建議最好保持默認。

  3. Eureka Client默認不會傳播當前應用的健康檢查狀態,一旦注冊成功,只要心跳存在,Eureka總是認為應用處於UP狀態。可以啟用Eureka的健康檢查,將狀態傳播給Eureka,其它應用只會將請求發給UP狀態的服務實例 eureka.client.healthcheck.enabled=true。注意這個配置只能配置在application.yml中,配置在bootstrap.yml中可能導致注冊服務時,服務以狀態為UNKOWN進行注冊。

  4. Eureka Server是沒有后端存儲的,服務實例需要通過心跳來更新注冊信息,注冊信息存於內存中,Eureka Client也有一個基於內存的緩存,不需要每次請求服務都要訪問注冊中心獲取服務地址信息。

  5. Eureka的自我保護機制:Eureka Server在短時間內丟失比較多的客戶端時,會進入自我保護模式,在該模式下,Eureka Server即使發現服務實例已經不再發送心跳了,也不會從服務注冊表中刪除。這樣,當發生網絡故障時,服務注冊信息仍然存於Eureka中,當網絡故障恢復后,會自動退出自我保護模式。自我保護模式是一種應對網絡異常的安全保護機制。相關配置: eureka.server.renewal-percent-threshold, 觸發自我保護機制的閾值,默認為0.85; eureka.server.enable-self-preservation, 自我保護開啟,默認為true,如果設置為false,則關閉客戶端程序后,可直觀地從Eureka Server的頁面發現服務實例被注銷刪除了。

本文示例代碼

 


    認真生活,快樂分享

    歡迎關注公眾號:空山新雨的技術空間

 

 

 

有道詞典
<dependency> ...
詳細 X
  <依賴>   < groupId > org.springframework.cloud < / groupId >   < artifactId > spring-cloud-starter-netflix-eureka-server < / artifactId >   < / >的依賴

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM