Spring Cloud Eureka Server高可用之:在線擴(kuò)容

Profile

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


概述

業(yè)務(wù)微服務(wù)化以后,我們要求服務(wù)高可用,于是我們可以部署多個(gè)相同的服務(wù)實(shí)例,并引入負(fù)載均衡機(jī)制。而微服務(wù)注冊(cè)中心作為微服務(wù)化系統(tǒng)的重要單元,其高可用也是非常必要的,因此在生產(chǎn)中我們可能需要多個(gè)微服務(wù)注冊(cè)中心實(shí)例來(lái)保證服務(wù)注冊(cè)中心的穩(wěn)定性。本文就以 Eureka微服務(wù)注冊(cè)中心為例,來(lái)實(shí)踐一下如何 在線擴(kuò)充 Eureka Server實(shí)例來(lái)保證 微服務(wù)注冊(cè)中心的高可用性!

注: 本文首發(fā)于 My Personal Blog,歡迎光臨 小站

本文內(nèi)容腦圖如下:

本文內(nèi)容腦圖

原理與實(shí)驗(yàn)流程介紹

我們欲模擬如下過(guò)程:

  • 首先啟動(dòng)一個(gè) eureka-server實(shí)例(eureka-server-1)

  • 再啟動(dòng)一個(gè) eureka-client實(shí)例(eureka-client-1)并注冊(cè)到 eureka-server-1中

  • 接下來(lái)我們啟動(dòng)第二個(gè) eureka-server實(shí)例:eureka-server-2,并且讓已啟動(dòng)的 eureka-server-1 和 eureka-client-1在不重啟的情況下來(lái)感知到 eureka-server-2的加入

  • 同理我們可以在啟動(dòng)第三個(gè) eureka-server實(shí)例:eureka-server-3,并且讓已啟動(dòng)的 eureka-server-1 、eureka-server-2 和 eureka-client-1 在不重啟的情況下來(lái)感知到 eureka-server-3的加入

  • 更多 eureka-server實(shí)例的加入原理完全相同,不再贅述

這樣一來(lái)我們便實(shí)現(xiàn)了微服務(wù)注冊(cè)中心的動(dòng)態(tài)在線擴(kuò)容!

而如何才能讓已啟動(dòng)的服務(wù)能夠在不重啟的情況下來(lái)感知到新的 eureka-server 的加入呢?

為此我們引入 Spring Cloud Config 配置中心 config-server,并將 eureka-server和 eureka-client服務(wù)的配置文件由 config-server進(jìn)行統(tǒng)一管理,這樣一來(lái)對(duì)配置文件的修改如果可以通過(guò)某種機(jī)制來(lái)通知已啟動(dòng)的服務(wù),那么問(wèn)題便迎刃而解了!

我們給出整個(gè)過(guò)程的原理圖如下:

實(shí)驗(yàn)原理圖

接下來(lái)我們來(lái)實(shí)踐這整個(gè)過(guò)程!


基礎(chǔ)工程搭建

  • 創(chuàng)建一個(gè) config-server工程

pom中關(guān)鍵依賴如下:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

主類添加相應(yīng)注解:

@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配置很重要,其連接了預(yù)先準(zhǔn)備好的 git倉(cāng)庫(kù),后續(xù) eureka-server 和 eureka-client 的配置文件都是存于該git倉(cāng)庫(kù)中的!

  • 創(chuàng)建一個(gè) eureka-server工程

pom中關(guān)鍵依賴如下:

        <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>

主類添加相應(yīng)注解:

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

bootstrap.yml重要配置如下:

spring:
  application:
    name: eureka-server
  cloud:
    config:
      uri: http://localhost:1115

注意該 yml中關(guān)于 spring cloud config 的配置同樣非常重要,因?yàn)榇?eureka-server需要從 config-server中拉取配置!

最后我們還需要添加一個(gè) controller便于測(cè)試:

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

    @Autowired
    EurekaClientConfigBean eurekaClientConfigBean;

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

這個(gè) Rest Controller 接口的意圖很簡(jiǎn)單:打印出當(dāng)前到底有多少個(gè) eureka-server實(shí)例在提供服務(wù)(從而可以直觀的判斷出 eureka-server的擴(kuò)容是否已經(jīng)成功)

  • 創(chuàng)建一個(gè) eureka-client工程

pom中關(guān)鍵依賴如下:

        <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>

主類添加相應(yīng)注解:

@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中添加一個(gè) controller便于測(cè)試:

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

    @Autowired
    EurekaClientConfigBean eurekaClientConfigBean;

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

三個(gè)工程的創(chuàng)建到此完畢!下來(lái)我們來(lái)依次啟動(dòng)各個(gè)工程

  • 首先啟動(dòng) config-server工程

  • 然后用 peer1配置文件來(lái)啟動(dòng) 第一個(gè)eureka server,指令如下:

mvn spring-boot:run -Dspring.profiles.active=peer1

啟動(dòng)過(guò)程的開(kāi)始打印出如下信息,一目了然:

用 peer1配置文件來(lái)啟動(dòng)第一個(gè)eureka server

當(dāng)然這個(gè) peer1配置文件實(shí)際物理存在于git倉(cāng)庫(kù)之上:

peer1配置文件的配置
  • 接下來(lái)我們啟動(dòng) eureka_client工程,指令如下:
mvn spring-boot:run -Dspring.profiles.active=peer1

其依然需要通過(guò) spring cloud config 去git倉(cāng)庫(kù)拉取 eureka-client的 peer1配置文件,這一點(diǎn)從 eureka-client的啟動(dòng)過(guò)程中也能看到:

啟動(dòng)eureka-client
  • 接下來(lái)我們用瀏覽器訪問(wèn)僅存在的一個(gè) eureka-server微服務(wù)注冊(cè)中心,可以看到有服務(wù)已經(jīng)注冊(cè)上去了:
微服務(wù)注冊(cè)中心

既然 config-server / eureka-server / eureka-client 三個(gè)服務(wù)已經(jīng)啟動(dòng)了,那么接下來(lái)我們來(lái)測(cè)試一下:

瀏覽器訪問(wèn) eureka-client的 Rest接口:localhost:1114/test/eureka-service-info

訪問(wèn) eureka-client的 Rest接口

同理,瀏覽器訪問(wèn) eureka-server的 Rest接口:localhost:1111/test/eureka-service-info

訪問(wèn) eureka-server的 Rest接口

OK,一切正常,但目前微服務(wù)注冊(cè)中心僅一個(gè) eureka-server實(shí)例,下來(lái)我們來(lái) 在線動(dòng)態(tài)擴(kuò)容微服務(wù)注冊(cè)中心實(shí)例


擴(kuò)充一次 Eureka Server

接下來(lái)我們?cè)儆?peer2配置文件來(lái) 啟動(dòng)第二個(gè) eureka server,指令如下:

mvn spring-boot:run -Dspring.profiles.active=peer2

啟動(dòng)完畢后,瀏覽器訪問(wèn)微服務(wù)注冊(cè)中心第一個(gè)實(shí)例 eureka-server-1:localhost:1111/
發(fā)現(xiàn)第二個(gè)微服務(wù)注冊(cè)中心實(shí)例 eureka-server-2已經(jīng)成功啟動(dòng)并加入

第二個(gè)微服務(wù)注冊(cè)中心實(shí)例 eureka-server-2已經(jīng)成功啟動(dòng)并加入

為了讓已啟動(dòng)的 eureka-client和 eureka-server-1能在線感知到 eureka-server-2的加入,此時(shí)我們需要修改兩個(gè)地方:

  • 修改 Git上eureka-client的配置文件:
server:
  port: 1114

spring:
  application:
    name: eureka-client

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:1111/eureka/,http://localhost:1112/eureka/  # 此處改為包含兩個(gè)eureka-server
  • 修改 Git上第一個(gè)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/ # 此處改為第二個(gè)eureka-server地址
  server:
      waitTimeInMsWhenSyncEmpty: 0
      enableSelfPreservation: false

Git倉(cāng)庫(kù)里配置文件的修改完畢并不能觸發(fā)已啟動(dòng)的 eureka-client和 eureka-server-1 在線更新,我們還需要向 eureka-client服務(wù)和 eureka-server-1服務(wù)來(lái) POST兩個(gè)請(qǐng)求來(lái)激活剛才所修改的配置:

POST localhost:1111/actuator/refresh  // 激活 eureka-client服務(wù)的配置
POST localhost:1114/actuator/refresh // 激活 eureka-server-1 服務(wù)的配置

POST請(qǐng)求一旦發(fā)出,我們從控制臺(tái)里能直觀看到更新配置文件的詳情:

POST觸發(fā)更新配置文件

配置文件更新完畢,瀏覽器再次訪問(wèn) eureka-client的 Rest接口:localhost:1114/test/eureka-service-info

瀏覽器再次訪問(wèn) eureka-client的 Rest接口

再擴(kuò)充一次 Eureka Server

接下來(lái)還可以再用 peer3配置文件來(lái)啟動(dòng)第三個(gè) eureka server加入高可用微服務(wù)注冊(cè)中心集群,過(guò)程和上面類似,此處不再贅述!當(dāng)然更多 eureka-server實(shí)例的擴(kuò)充原理也相同。


后記

由于能力有限,若有錯(cuò)誤或者不當(dāng)之處,還請(qǐng)大家批評(píng)指正,一起學(xué)習(xí)交流!



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容