Spring Cloud Eureka Server高可用之:線上擴容

CodeSheep發表於2018-10-18

本文共 1591字,閱讀大約需要 6分鐘 !


概述

業務微服務化以後,我們要求服務高可用,於是我們可以部署多個相同的服務例項,並引入負載均衡機制。而微服務註冊中心作為微服務化系統的重要單元,其高可用也是非常必要的,因此在生產中我們可能需要多個微服務註冊中心例項來保證服務註冊中心的穩定性。本文就以 Eureka微服務註冊中心為例,來實踐一下如何 線上擴充 Eureka Server例項來保證 微服務註冊中心的高可用性!

注: 本文首發於 My Personal Blog,歡迎光臨 小站

本文內容腦圖如下:

本文內容腦圖


原理與實驗流程介紹

我們欲模擬如下過程:

  • 首先啟動一個 eureka-server例項(eureka-server-1)

  • 再啟動一個 eureka-client例項(eureka-client-1)並註冊到 eureka-server-1中

  • 接下來我們啟動第二個 eureka-server例項:eureka-server-2,並且讓已啟動的 eureka-server-1 和 eureka-client-1在不重啟的情況下來感知到 eureka-server-2的加入

  • 同理我們可以在啟動第三個 eureka-server例項:eureka-server-3,並且讓已啟動的 eureka-server-1 、eureka-server-2 和 eureka-client-1 在不重啟的情況下來感知到 eureka-server-3的加入

  • 更多 eureka-server例項的加入原理完全相同,不再贅述

這樣一來我們便實現了微服務註冊中心的動態線上擴容!

而如何才能讓已啟動的服務能夠在不重啟的情況下來感知到新的 eureka-server 的加入呢?

為此我們引入 Spring Cloud Config 配置中心 config-server,並將 eureka-server和 eureka-client服務的配置檔案由 config-server進行統一管理,這樣一來對配置檔案的修改如果可以通過某種機制來通知已啟動的服務,那麼問題便迎刃而解了!

我們給出整個過程的原理圖如下:

實驗原理圖

接下來我們來實踐這整個過程!


基礎工程搭建

  • 建立一個 config-server工程

pom中關鍵依賴如下:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
複製程式碼

主類新增相應註解:

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
  ...
}
複製程式碼

bootstrap.yml配置檔案如下:

spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/hansonwang99/xxxx
          username: xxxx
          password: xxxx
server:
  port: 1115
複製程式碼

該 yml配置很重要,其連線了預先準備好的 git倉庫,後續 eureka-server 和 eureka-client 的配置檔案都是存於該git倉庫中的!

  • 建立一個 eureka-server工程

pom中關鍵依賴如下:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
複製程式碼

主類新增相應註解:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
  ...
}

複製程式碼

bootstrap.yml重要配置如下:

spring:
  application:
    name: eureka-server
  cloud:
    config:
      uri: http://localhost:1115
複製程式碼

注意該 yml中關於 spring cloud config 的配置同樣非常重要,因為此 eureka-server需要從 config-server中拉取配置!

最後我們還需要新增一個 controller便於測試:

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    EurekaClientConfigBean eurekaClientConfigBean;

    @GetMapping("/eureka-service-info")
    public Object getEurekaServerUrl(){
        return eurekaClientConfigBean.getServiceUrl();
    }
}
複製程式碼

這個 Rest Controller 介面的意圖很簡單:列印出當前到底有多少個 eureka-server例項在提供服務(從而可以直觀的判斷出 eureka-server的擴容是否已經成功)

  • 建立一個 eureka-client工程

pom中關鍵依賴如下:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
複製程式碼

主類新增相應註解:

@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientApplication.class, args);
    }
}
複製程式碼

bootstrap.yml 重要配置如下:

spring:
  application:
    name: eureka-client
  cloud:
    config:
      uri: http://localhost:1115
複製程式碼

這裡基本同上面 eureka-server的配置,不再贅述

同樣,我們也在 eureka-client中新增一個 controller便於測試:

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    EurekaClientConfigBean eurekaClientConfigBean;

    @GetMapping("/eureka-service-info")
    public Object getEurekaServerUrl(){
        return eurekaClientConfigBean.getServiceUrl();
    }
}
複製程式碼

三個工程的建立到此完畢!下來我們來依次啟動各個工程

  • 首先啟動 config-server工程

  • 然後用 peer1配置檔案來啟動 第一個eureka server,指令如下:

mvn spring-boot:run -Dspring.profiles.active=peer1
複製程式碼

啟動過程的開始列印出如下資訊,一目瞭然:

用 peer1配置檔案來啟動第一個eureka server

當然這個 peer1配置檔案實際物理存在於git倉庫之上:

peer1配置檔案的配置

  • 接下來我們啟動 eureka_client工程,指令如下:
mvn spring-boot:run -Dspring.profiles.active=peer1
複製程式碼

其依然需要通過 spring cloud config 去git倉庫拉取 eureka-client的 peer1配置檔案,這一點從 eureka-client的啟動過程中也能看到:

啟動eureka-client

  • 接下來我們用瀏覽器訪問僅存在的一個 eureka-server微服務註冊中心,可以看到有服務已經註冊上去了:

微服務註冊中心

既然 config-server / eureka-server / eureka-client 三個服務已經啟動了,那麼接下來我們來測試一下:

瀏覽器訪問 eureka-client的 Rest介面:localhost:1114/test/eureka-service-info

訪問 eureka-client的 Rest介面

同理,瀏覽器訪問 eureka-server的 Rest介面:localhost:1111/test/eureka-service-info

訪問 eureka-server的 Rest介面

OK,一切正常,但目前微服務註冊中心僅一個 eureka-server例項,下來我們來 線上動態擴容微服務註冊中心例項


擴充一次 Eureka Server

接下來我們再用 peer2配置檔案來 啟動第二個 eureka server,指令如下:

mvn spring-boot:run -Dspring.profiles.active=peer2
複製程式碼

啟動完畢後,瀏覽器訪問微服務註冊中心第一個例項 eureka-server-1:localhost:1111/ 發現第二個微服務註冊中心例項 eureka-server-2已經成功啟動並加入

第二個微服務註冊中心例項 eureka-server-2已經成功啟動並加入

為了讓已啟動的 eureka-client和 eureka-server-1能線上感知到 eureka-server-2的加入,此時我們需要修改兩個地方:

  • 修改 Git上eureka-client的配置檔案:
server:
  port: 1114

spring:
  application:
    name: eureka-client

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:1111/eureka/,http://localhost:1112/eureka/  # 此處改為包含兩個eureka-server
複製程式碼
  • 修改 Git上第一個eureka-server(eureka-server-1)的配置檔案:
server:
  port: 1111

spring:
  application:
    name: eureka-server
eureka:
  instance:
    hostname: localhost
    preferIpAddress: true
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://localhost:1112/eureka/ # 此處改為第二個eureka-server地址
  server:
      waitTimeInMsWhenSyncEmpty: 0
      enableSelfPreservation: false
複製程式碼

Git倉庫裡配置檔案的修改完畢並不能觸發已啟動的 eureka-client和 eureka-server-1 線上更新,我們還需要向 eureka-client服務和 eureka-server-1服務來 POST兩個請求來啟用剛才所修改的配置:

POST localhost:1111/actuator/refresh  // 啟用 eureka-client服務的配置
POST localhost:1114/actuator/refresh // 啟用 eureka-server-1 服務的配置
複製程式碼

POST請求一旦發出,我們從控制檯裡能直觀看到更新配置檔案的詳情:

POST觸發更新配置檔案

配置檔案更新完畢,瀏覽器再次訪問 eureka-client的 Rest介面:localhost:1114/test/eureka-service-info

瀏覽器再次訪問 eureka-client的 Rest介面


再擴充一次 Eureka Server

接下來還可以再用 peer3配置檔案來啟動第三個 eureka server加入高可用微服務註冊中心叢集,過程和上面類似,此處不再贅述!當然更多 eureka-server例項的擴充原理也相同。


後記

由於能力有限,若有錯誤或者不當之處,還請大家批評指正,一起學習交流!



長按掃描 下面的 小心心 來訂閱作者公眾號 CodeSheep,獲取更多 務實、能看懂、可復現的 原創文 ↓↓↓

CodeSheep · 程式羊


相關文章