1. 程式人生 > >Spring Cloud 探索 | 服務註冊與發現 Eureka(上)

Spring Cloud 探索 | 服務註冊與發現 Eureka(上)

先在這裡宣告一下:這一系列的文章都是自己查詢網上資料學習而來,不可避免有些內容從其他地方copy過來,如有侵犯請聯絡我刪除,謝謝!(引用部分都會添加註腳

本系列文章的寫作環境為:Spring Boot 2.0.7.RELEASESpring Cloud Finchley.SR2JDK 1.8.0_131IntelliJ IDEA ULTIMATE 2018.1。並沒有使用最新版本的Spring Cloud進行學習,原因是新版本還不穩定,存在很多問題,不要把時間花費在無謂的BUG上。

1 Spring Cloud Eureka 介紹


上篇文章簡單介紹了Spring Cloud和微服務架構之後,下面迴歸本文的主旨內容,如何使用Spring Cloud來實現服務治理

由於Spring Cloud為服務治理做了一層抽象介面,所以在Spring Cloud應用中可以支援多種不同的服務治理框架,比如:Netflix Eureka、Consul、Zookeeper。在Spring Cloud服務治理抽象層的作用下,我們可以無縫地切換服務治理實現,並且不影響任何其他的服務註冊、服務發現、服務呼叫等邏輯。1

Eureka是 Netflix 開源的一款基於REST(Representational State Transfer)風格的服務發現框架,目前已被 Spring Cloud 整合在其子專案 spring-cloud-netflix 中,用於 Spring Cloud 的服務註冊發現功能。

下面,就來具體看看如何使用Spring Cloud Eureka實現服務治理。

2 Spring Cloud Eureka 工作過程


Eureka包含了伺服器端客戶端元件。伺服器端,也被稱作是服務註冊中心,用於提供服務的註冊與發現。

客戶端元件包含服務消費者服務生產者。在應用程式執行時,Eureka客戶端向Eureka服務端註冊自身提供的服務並週期性的傳送心跳來更新它的服務租約。同時也可以從服務端查詢當前註冊的服務資訊並把他們快取到本地並週期性的重新整理服務狀態。2

當一個Eureka客戶端註冊到Eureka服務端,它會提供關於它自己的埠、地址、健康監控URL和Home頁面等等的元資料,服務端會從每個例項接受心跳資訊。如果心跳在配置的時間內失敗,例項通常會從登錄檔中移除。

Eureka支援高可用的配置(圖中沒有畫出來,後邊會有講解),當叢集中有分片出現故障時,Eureka就會轉入自動保護模式,它允許分片故障期間繼續提供服務的發現和註冊,當故障分片恢復正常時,叢集中其他分片會把他們的狀態再次同步回來。

關係調用說明:

  • 服務生產者啟動時,向服務註冊中心註冊自己提供的服務;
  • 服務消費者啟動時,在服務註冊中心訂閱自己所需要的服務;
  • 註冊中心返回服務提供者的地址資訊給消費者;
  • 消費者從提供者中呼叫服務;

3 Spring Cloud Eureka Server 配置過程


3.1 pom.xml 新增依賴

Eureka 服務端我們只需要新增一個依賴就可以。

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

3.2 配置啟動類

通過@EnableEurekaServer註解啟動一個服務註冊中心:

@SpringBootApplication
@EnableEurekaServer
public class SpringCloudEurekaServerApplication {

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

}

到此,我們 Eureka Server 就算是搭建完成了,是不是so easy。但是,如果直接啟動的話會報錯,原因請看 3.3 application.yml基礎配置

3.3 application.yml基礎配置

下面是一個Eureka伺服器最基本的配置:

spring: 
  application: 
    name: eureka-server
server: 
  port: 9000
eureka: 
  instance: 
    hostname: eureka-server.com
  client: 
    fetch-registry: false
    register-with-eureka: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
logging.level.root: info

配置解釋:

  • eureka.instance: 對eureka例項進行配置的部分;
  • eureka.instance.hostname:定義 eureka 例項所在的主機名稱。在C:\Windows\System32\drivers\etc\hosts檔案中新增如下內容:127.0.0.1 eureka-server.com,然後我們就可以使用http://eureka-server.com:9000/來訪問 eureka 的資訊展示頁面;
  • eureka.client:客戶端進行 eureka 註冊的配置;
  • eureka.client.fetch-registry:是否從 eureka 伺服器上獲取註冊資訊,預設為 true,此處建議修改成 false(單機設定的意義不大。如果設定成 true,啟動時會去抓取一次登錄檔,獲取不到更新快取就會出錯(該錯誤不影響 eureka 正常使用));
  • eureka.client.register-with-eureka:在預設設定下,該服務註冊中心也會將自己作為客戶端來嘗試註冊它自己,所以我們需要禁用它的客戶端註冊行為;
  • eureka.client.service-url.defaultZone:指定服務註冊中心的位置。預設註冊地址 this.serviceUrl.put("defaultZone", "http://localhost:8761/eureka/");,此處的 defaultZone 千萬別寫成 default-zone。另外,請注意,serviceUrl指向與本地例項相同的主機。

預設情況下,每個Eureka伺服器也是一個Eureka客戶端,所以需要(至少一個)服務URL來定位Eureka伺服器。如果不提供,Eureka伺服器也會執行和工作,但會產生大量無法註冊到Eureka伺服器的日誌。

3.4 Controller、Service等

Eureka Server 不需要Controller、Service等,只需簡單配置就可以。

3.5 配置/測試/展示結果

3.5.1 訪問 eureka

此時,訪問 eureka(頁面上東西很多,我只截取了部分):對於頁面上的各部分不理解沒關係,後面會講解

3.5.2 設定登錄檔的更新時間

在實際的專案執行過程之中需要通過 Eureka 作為所有微服務的監控處理程式,但是對於監控程式那麼就必然要面臨以下問題:

  • 新服務追加的時候應該立刻可以進行註冊;
  • 當某一個服務下線之後應該可以進行清理;

在 application.yml 檔案中新增如下配置項:

eureka:
  server:
    eviction-interval-timer-in-ms: 5000

配置解釋:

  • eureka.server.eviction-interval-timer-in-ms: 設定登錄檔的清理間隔(預設是60 * 1000 毫秒)。單位:毫秒

可以看到,登錄檔的清理間隔已經變成每5秒清理一次了。

一般情況下,該配置不建議進行修改,預設就是 60 秒,也就是說你的微服務如果 60 秒沒有心跳了,那麼就認為可以清理掉。

3.5.3 Eureka 自我保護模式3

自我保護模式是Eureka的重要特性。進入自我保護模式最直觀的體現,是Eureka Server首頁輸出的警告:

預設情況下,如果Eureka Server在一定時間內沒有接收到某個微服務例項的心跳,Eureka Server將會登出該例項(預設90秒)。但是當網路分割槽故障發生時,微服務與Eureka Server之間無法正常通訊,以上行為可能變得非常危險了——因為微服務本身其實是健康的,此時本不應該登出這個微服務。

Eureka通過“自我保護模式”來解決這個問題——當Eureka Server節點在短時間內丟失過多客戶端時(可能發生了網路分割槽故障),那麼這個節點就會進入自我保護模式。一旦進入該模式,Eureka Server就會保護服務登錄檔中的資訊,不再刪除服務登錄檔中的資料(也就是不會登出任何微服務)。當網路故障恢復後,該Eureka Server節點會自動退出自我保護模式。

綜上,自我保護模式是一種應對網路異常的安全保護措施。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目登出任何健康的微服務。使用自我保護模式,可以讓Eureka叢集更加的健壯、穩定。

在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false 禁用自我保護模式。

3.5.3 Eureka 安全配置

可以註冊的服務是能夠滿足於認證要求的微服務,所以這樣一來在之前所進行的 Eureka 裡面配置缺少關鍵性的一步: 安全認證,所以應該為 Eureka 配置上安全認證處理。

新增依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

一旦我們的專案之中匯入了 Security 開發包,則每一次啟動微服務的時候都會自動生成一個密碼, 而這個密碼由於會改變,所以一般都不使用。要修改 application.yml 配置檔案,追加密碼的配置項:

spring.security.user.name: lpf
spring.security.user.password: root

此時再訪問Eureka就需要輸入密碼了:
在這裡插入圖片描述
這裡需要注意:如果只是簡單進行上面的配置,Eureka Client是不能成功註冊到Eureka Server上的。

原因是由於新版的Spring Security會預設開啟防 csrf 攻擊,所有的請求都必須攜帶 crsf 這個引數,但是Eureka Client去註冊時是沒有的。所以我們需要主動去關閉,在Eureka Server新增以下配置:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    	http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic();
    }
}

注意:新增安全配置後eureka.client.service-url.defaultZone需要進行修改,改成:http://${spring.security.user.name}:${spring.security.user.password}@${eureka.instance.hostname}:${server.port}/eureka/

未完,請看下文……


  1. Spring Cloud構建微服務架構:服務註冊與發現(Eureka、Consul)【Dalston版】 ↩︎

  2. 一起來學Spring Cloud(F版) | 第一篇:認識Eureka ↩︎

  3. 理解Eureka的自我保護模式 ↩︎