Spring Cloud Eureka 服務註冊中心(二)

序言

Eureka 是 Netflix 開發的,一個基於 REST 服務的,服務註冊與發現的組件html

它主要包括兩個組件:Eureka Server 和 Eureka Clientjava

  • Eureka Client:一個Java客戶端,用於簡化與 Eureka Server 的交互(一般就是微服務中的客戶端和服務端)
  • Eureka Server:提供服務註冊和發現的能力(一般就是微服務中的註冊中心)

各個微服務啓動時,會經過 Eureka Client 向 Eureka Server 註冊本身,Eureka Server 會存儲該服務的信息git

也就是說,每一個微服務的客戶端和服務端,都會註冊到 Eureka Server,這就衍生出了微服務相互識別的話題github

  • 同步:每一個 Eureka Server 同時也是 Eureka Client(邏輯上的)
       多個 Eureka Server 之間經過複製的方式完成服務註冊表的同步,造成 Eureka 的高可用
  • 識別:Eureka Client 會緩存 Eureka Server 中的信息
       即便全部 Eureka Server 節點都宕掉,服務消費者仍可以使用緩存中的信息找到服務提供者(筆者已親測)
  • 續約:微服務會週期性(默認30s)地向 Eureka Server 發送心跳以Renew(續約)信息(相似於heartbeat)
  • 續期:Eureka Server 會按期(默認60s)執行一次失效服務檢測功能
       它會檢查超過必定時間(默認90s)沒有Renew的微服務,發現則會註銷該微服務節點

Spring Cloud 已經把 Eureka 集成在其子項目 Spring Cloud Netflix 裏面web

關於 Eureka 配置的最佳實踐,可參考:https://github.com/spring-cloud/spring-cloud-netflix/issues/203spring

更多介紹,可參考:http://cloud.spring.io/spring-cloud-static/Camden.SR4/#spring-cloud-eureka-server緩存

單個Eureka Server配置部署實例

pom.xml 安全

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

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Finchley.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

註冊中心,啓動類。網絡

@SpringBootApplication
//建立服務註冊中心
@EnableEurekaServer
public class StartMain {
    public static void main(String[] args) {
        SpringApplication.run(StartMain.class, args);
    }
}

註冊中心配置文件app

## server
server.port=8081

##eureka
#指定環境
eureka.environment=work
# 設置是否將本身做爲客戶端註冊到註冊中心(缺省true)
# 這裏爲不須要(查看@EnableEurekaServer註解的源碼,會發現它間接用到了@EnableDiscoveryClient)
eureka.client.register-with-eureka=false
# 設置是否從註冊中心獲取註冊信息(缺省true)
# 由於這是一個單點的EurekaServer,不須要同步其它EurekaServer節點的數據,故設爲false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
#是否開啓自我保護模式,默認爲true。
eureka.server.enable-self-preservation=true
#續期時間,即掃描失效服務的間隔時間(缺省爲60*1000ms)
eureka.server.eviction-interval-timer-in-ms=10000

zone

上面提到 serviceUrl,那就順便說下 defaultZone

Eureka 有一個 Region 和 Zone 的概念,你能夠理解爲現實中的大區(Region)和機房(Zone)

Eureka Client 在啓動時須要指定 Zone,它會優先請求本身 Zone 的 Eureka Server 獲取註冊列表

一樣的,Eureka Server 在啓動時也須要指定 Zone,若是沒有指定的話,其會默認使用 defaultZone

詳見源碼中的 getEurekaServerServiceUrls() 方法:https://github.com/spring-cloud/spring-cloud-netflix/blob/master/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java

note:

如今啓動Eureka Server,沒有Eureka Client,過一段時間會出現

     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進入保護模式,可經過上述配置去掉,Eureka的保護模式講解詳見:https://github.com/Netflix/eureka/wiki/Understanding-Eureka-Peer-to-Peer-Communication

Eureka Client配置部署實現

pom文件

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>        
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>
    </dependencies>
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

微服務client,啓動類。

@SpringBootApplication
@EnableEurekaClient
public class StartMain {
    public static void main(String[] args) {
        SpringApplication.run(StartMain.class, args);
    }
}

微服務client,配置文件

##eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/
eureka.instance.instance-id=${spring.application.name}:${server.port}
# 設置微服務調用地址爲IP優先(缺省爲false)
eureka.instance.prefer-ip-address=true
# 心跳時間,即服務續約間隔時間(缺省爲30s)
eureka.instance.lease-renewal-interval-in-seconds=30
# 發呆時間,即服務續約到期時間(缺省爲90s)
eureka.instance.lease-expiration-duration-in-seconds=90

note:

關於續約序言中有講解,instance-id,是再註冊中心頁面顯示的微服務名。

Eureka 首頁顯示的微服務名默認爲:機器主機名:應用名稱:應用端口,也就是:${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}

eureka.client.serviceUrl.defaultZone這個配置能夠配置單個註冊中心的地址,也可配置多個,逗號隔開

eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8000/eureka/,http://127.0.0.1:8081/eureka/

好啦,這樣一個註冊中心與微服務就完成啦。啓動看看吧。

Eureka Server註冊中心(高可用)集羣部署

Eureka Server 支持運行多實例,並以互相註冊的方式(即夥伴機制),來實現高可用的部署

即每一臺 Eureka 都在配置中指定另外一個 Eureka 或多個 地址做爲夥伴,它在啓動時會向夥伴節點獲取註冊列表

詳見:http://cloud.spring.io/spring-cloud-static/spring-cloud.html#_peer_awareness

配置demo

與單Server配置稍做改動,以下三個註冊中心ABC

A:127.0.0.1:9001

B:127.0.0.1:9002

C:127.0.0.1:9003

A配置: eureka.client.serviceUrl.defaultZone : http://B/eureka/,http://C/eureka/

B配置: eureka.client.serviceUrl.defaultZone : http://A/eureka/,http://C/eureka/

C配置: eureka.client.serviceUrl.defaultZone : http://B/eureka/,http://A/eureka/

運行不一樣環境

java -jar .\trade-0.0.1-SNAPSHOT.jar --spring.profiles.active=local

ok啦,試試吧。

配置

服務端

server:
  # 項目端口號
  port: 8761
  # SSL 配置
  ssl:
    # 開啓 SSL 認證
    enabled: true
    # 證書別名
    key-alias: eurekaserver
    # 證書存放路徑
    key-store: classpath:EurekaServer.p12
    # 證書密碼
    key-store-password: 123456
    # 存儲類型
    key-store-type: PKCS12

spring:
  application:
    name: demo-eureka-server
  # 開啓安全控制
  security:
    user:
      # 用戶名
      name: eureka-server
      # 密碼
      password: 8e9lx7LuP3436gfsg

eureka:
  instance:
    # 主機名
    hostname: localhost
    # 使用 ip 註冊到註冊中心實例化
    prefer-ip-address: true
    # 安全端口
    secure-port: ${server.port}
    # 指示是否應爲流量啓用安全端口
    secure-port-enabled: true
    # 關閉非安全端口
    non-secure-port-enabled: false
    home-page-url: https://${eureka.instance.hostname}:${server.port}/
    status-page-url: https://${eureka.instance.hostname}:${server.port}/actuator/info
    health-check-url: https://${eureka.instance.hostname}:${server.port}/actuator/health
  client:
    # 此實例是否從註冊中心獲取註冊信息
    fetch-registry: false
    # 是否將此實例註冊到註冊中心
    register-with-eureka: false
    # 註冊地址
    service-url:
      # 默認註冊分區地址
      defaultZone: https://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    # 同步爲空時,等待時間
    wait-time-in-ms-when-sync-empty: 0
    # 是否開啓自我保護機制
    ## 在分佈式系統設計裏頭,一般須要對應用實例的存活進行健康檢查,這裏比較關鍵的問題就是要處理好網絡偶爾抖動或短暫不可用時形成的誤判。另外Eureka Server端與Client端之間若是出現網絡分區問題,在極端狀況下可能會使得Eureka Server清空部分服務的實例列表,這個將嚴重影響到Eureka server的 availibility屬性。所以Eureka server引入了SELF PRESERVATION機制。
    ## Eureka client端與Server端之間有個租約,Client要定時發送心跳來維持這個租約,表示本身還存活着。 Eureka經過當前註冊的實例數,去計算每分鐘應該從應用實例接收到的心跳數,若是最近一分鐘接收到的續約的次數小於指定閾值的話,則關閉租約失效剔除,禁止定時任務剔除失效的實例,從而保護註冊信息。
    # 此處關閉能夠防止問題(測試環境能夠設置爲false):Eureka server因爲開啓並引入了SELF PRESERVATION模式,致使registry的信息不會由於過時而被剔除掉,直到退出SELF PRESERVATION模式才能剔除。
    enable-self-preservation: false
    # 指定 Eviction Task 定時任務的調度頻率,用於剔除過時的實例,此處未使用默認頻率,頻率爲:5/秒,默認爲:60/秒
    # 有效防止的問題是:應用實例異常掛掉,沒能在掛掉以前告知Eureka server要下線掉該服務實例信息。這個就須要依賴Eureka server的EvictionTask去剔除。
    eviction-interval-timer-in-ms: 5000
    # 設置read Write CacheMap的expire After Write參數,指定寫入多長時間後過時
    # 有效防止的問題是:應用實例下線時有告知Eureka server下線,可是因爲Eureka server的REST API有response cache,所以須要等待緩存過時才能更新
    response-cache-auto-expiration-in-seconds: 60
    # 此處不開啓緩存,上方配置開啓一個便可
    # use-read-only-response-cache: false
    # 指定每分鐘須要收到的續約次數的閾值,默認值就是:0.85
    renewal-percent-threshold: 0.85
    # 續約頻率提升,默認:30
    leaseRenewalIntervalInseconds: 10

客戶端

server:
  # \u9879\u76EE\u7AEF\u53E3\u53F7
  port: 11200

spring:
  application:
    # Spring Boot \u9879\u76EE\u5B9E\u4F8B\u540D\u79F0
    name: demo-goods

### \u6CE8\u518C\u4E2D\u5FC3\u914D\u7F6E
eureka:
  instance:
    # \u4E3B\u673A\u540D
    hostname: localhost
    # \u4F7F\u7528 ip \u6CE8\u518C\u5230\u6CE8\u518C\u4E2D\u5FC3\u5B9E\u4F8B\u5316
    prefer-ip-address: true
  client:
    secure-port-enabled: true
    ssl:
      key-store: EurekaClient.p12
      key-store-password: 123456
    security:
      user:
        name: eureka-server
        password: 8e9lx7LuP3436gfsg
    # Spring Cloud Eureka \u6CE8\u518C\u4E2D\u5FC3\u5730\u5740
    service-url:
      defaultZone: https://${eureka.client.security.user.name}:${eureka.client.security.user.password}@${eureka.instance.hostname}:8761/eureka/
    # \u9488\u5BF9\u65B0\u670D\u52A1\u4E0A\u7EBF, Eureka client\u83B7\u53D6\u4E0D\u53CA\u65F6\u7684\u95EE\u9898\uFF0C\u5728\u6D4B\u8BD5\u73AF\u5883\uFF0C\u53EF\u4EE5\u9002\u5F53\u63D0\u9AD8Client\u7AEF\u62C9\u53D6Server\u6CE8\u518C\u4FE1\u606F\u7684\u9891\u7387\uFF0C\u9ED8\u8BA4\uFF1A30\u79D2
    registry-fetch-interval-seconds: 30

總結

多看文檔,很容易理解的。

相關文章
相關標籤/搜索