Eureka學習記錄

SachinLea發表於2019-01-20

SpringCloud微服務註冊中心——Eureka

本文程式碼示例基於Spring Boot 2.0.7和Spring Cloud Finchley.SR2版本;

1. 服務發現

  原來我們服務間的呼叫,一般都是通過在消費者端配置生產者的ip和埠,來進行呼叫,但是,在微服務的環境中,服務數量可能會很多,而且,服務之間可能呼叫關係也會很多,如果還是配置ip和埠來互相呼叫的話,這個配置的工作就很龐雜,同時,如果某個微服務的ip發生了變化,那麼帶來的維護工作,也會很複雜。
  因此,微服務中引入了服務發現元件,也就是註冊中心,一般使用Eureka,也有其他的元件,Consul,zookeeper等。實際使用中,將微服務都註冊到註冊中心,註冊中已經包含了微服務的ip等資訊,這樣,微服務之間互相呼叫時,就可以現在註冊中心獲取對應微服務的ip資訊。這樣就不用自己維護很多的配置檔案了。

1.1 Eureka簡介

  Eureka是Netflix開源的服務發現元件,本身是一個基於REST的服務,包含Server和Client兩部分,Spring Cloud將它整合在子專案Spring Cloud Netflix中。在微服務系統中,我們需要單獨建立一個Eureka Server作為註冊中心,其他的微服務就相當於客戶端,註冊到我們的註冊中心中。

2. Eureka的使用

2.1 基本使用

2.1.1 建立Eureka Server

  1. 建立一個Spring Boot專案,新增依賴,這裡使用版本是Finchley.SR2
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
複製程式碼
  1. 啟動類上新增註解@EnableEurekaServer
  2. 配置檔案
server:
  port: 8761

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:8761/eureka/
複製程式碼

配置解析:

  • eureka.client.register-with-eureka=false 表示是否將自己註冊到Eureka Server,預設值true
  • eureka.client.fetch-registry=false 表示是否從Eureka Server獲取資訊,預設值ture
  • eureka.client.serviceUrl.defaultZone: 表示Eureka Server的地址,如果有多個,使用逗號分隔。

2.1.2 建立一個微服務

  1. 建立一個Spring Boot專案,引入依賴,由於我使用的是Finchley.SR2版本,需要引入web依賴:
<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>
複製程式碼
  1. 啟動類新增註解@EnableDiscoveryClient 該註解,從Edgware版本開始,也可以省略不寫
  2. 配置檔案
server:
  port: 8762
spring:
  application:
    name: auth-server
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
複製程式碼
  • spring.application.name: 表示註冊到Eureka Server中服務名

啟動兩個服務,直接訪問Eureka Server地址,結果如圖

在這裡插入圖片描述
  可以看到,服務註冊成功;這樣,如果有多個服務之間互相呼叫,就可以從Eureka Server中獲取到對應服務的資訊,這裡暫時先不演示;   但是,存在一個問題,服務註冊時,預設都是通過hostname來註冊的,也就是這裡的localhost,但是,如果服務不在同一個伺服器上,顯然是呼叫不了的,因此,我們再客戶端增加一個配置:

  • eureka.instance.prefer-ip-address=true : 表示將自己的ip註冊到Eureka Server。此時,雖然註冊中心皮膚上還是hostname,但是,實際訪問時已經時通過ip來訪問了。可以點選皮膚上status列上的連結驗證。

  另外,如果客戶端所在的伺服器,有多個網路卡的情況下,使用這種方式,怎麼知道註冊哪個ip呢?   Spring Cloud提供了按需選擇ip的能力:

  • 忽略指定名稱的網路卡:
spring:
  cloud:
    inetutils:
      ignoredInterfaces:
        - docker0
        - veth.*
        - VM.*
複製程式碼
  • 使用正規表示式,指定使用的網路地址:
spring:
  cloud:
    inetutils:
      preferredNetworks:
        - 192.168
複製程式碼
  • 只是用站點本地地址:
spring:
	cloud:
		inetutils:
			use-only-site-local-interfaces: true
複製程式碼
  • 手動指定ip地址:
eureka:
	instance:
		ip-address: 127.0.0.1
複製程式碼

2.2 身份驗證

  上邊的例子中,已經展示了Eureka的基本用法,其中Eureka的控制檯,只要輸入對應的ip和埠,就可以訪問,這肯定不符合企業的安全規範,一般情況下都是需要輸入一個使用者名稱和密碼;這裡展示簡單的使用Security來新增註冊中心的身份驗證:

  1. 引入security依賴
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-security</artifactId>
 </dependency>
複製程式碼
  1. 配置檔案中配置使用者名稱和密碼 2.0之前的配置
security:
	basic:
		enable: true # 開啟基於HTTP basic的認證
	user:
		name: root
		password: root
複製程式碼

  以上配置完成後,使用瀏覽器訪問Eureka Server,就會提示輸入使用者名稱和密碼,才能訪問;那麼,註冊中心增加了身份驗證之後,微服務要如何才能註冊呢?   微服務的註冊,只需要將配置Eureka Server的地址新增上使用者名稱和密碼就可以了,具體配置為:

eureka:
  client:
    service-url:
    # http://username:password@EUREKA_HOST:EUREKA_PORT/eureka/
      defaultZone: http://root:root@localhost:8761/eureka/
複製程式碼

由於,我使用的Spring Boot版本為2.0.7.RELEASE,Eureka Server配置需要稍作修改: Spring Boot 2.0中security捨棄了一些配置,因此配置需要修改如下:

spring:
	security:
		user:
			name: root
			password: root
複製程式碼

然後,需要增加配置類,否則客戶端註冊會報錯,cannot execute any request on any know server:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic();
    }
}
複製程式碼

2.3 自我保護

  如果Eureka Server在一定時間內沒有收到微服務例項的心跳,會將該微服務登出,即從登錄檔中移除;但是,有時候因為網路或者其他的原因沒有收到心跳,例項還是正常可用,這種情況下,如果將例項從登錄檔中移除,訪問該微服務本來是應該正常了,卻導致了訪問失敗,造成系統的誤報同時難以排查問題;   為了防止上述情況發生,Eureka Server預設開啟了自我保護機制,如果短時間內,註冊中心丟失了過多的客戶端,Eureka Server會進入自我保護狀態,該狀態下,會保護登錄檔中的資訊,不會從登錄檔中刪除資料,也就是,雖然沒有收到微服務例項的心跳,但是,還會儲存該例項的註冊資訊,不會將之移除。   如果不想讓Eureka Server使用自我保護機制,我們可以在配置檔案中增加如下配置:

eureka:
  server:
    enable-self-preservation: false
複製程式碼

2.4 健康檢查

  根據前文中圖片,微服務例項的狀態對應的是UP,表示該服務可用;我們也知道了Eureka Server通過心跳來驗證微服務是否正常;但是,有時候微服務正常執行,也不一定可用,可能微服務中的某個元件不可用,或者,資料來源連線不上,導致微服務不可用;但是,Eureka Server通過心跳並不能獲取這些資訊,還是會顯示UP狀態,因此,我們還需要對客戶端進行健康檢查。   微服務的健康檢查,基於actuator包,因此,在客戶端需要引入依賴,

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
複製程式碼

(ps: 引入依賴後,啟動類微服務,在IDE控制檯可以看到,增加了幾個請求路徑,/actuator/health,/actuator/info等,Spring Boot 2.0之前可能是/health,/info;我們可以手動請求該路徑,檢視微服務的健康狀態) 然後,增加配置,啟動健康檢查,將健康狀態傳播到Eureka Server

eureka:
  client:
    healthcheck:
      enabled: true
複製程式碼

2.5 Eureka Server的高可用

  前文描述的Eureka Server都是單機狀態,如果,我們想要實現高可用,搭建Eureka Server叢集,也非常簡單,只需要將Eureka Server作為微服務註冊到其他的Server中;其他的微服務註冊,原來的地址直接配置多個就可以了,使用逗號分隔,例如:

eureka:
  client:
    service-url:
      defaultZone: http://username:password@localhost:8761/eureka/,http://username:password@localhost:8762/eureka
複製程式碼

Eureka Server和普通的微服務例項配置類似,只是url中,不包含自己的,也就是前文所說的註冊到其他的Server。

參考

  1. 《Spring Cloud微服務實戰》——作者部落格
  2. 《Spring Cloud與Docker微服務架構實戰》——作者部落格

相關文章