天天看點

注冊中心遷移Eureka到Nacos

注冊中心遷移

    • 雙注冊雙訂閱中心
    • 注冊中心遷移
    • Eureka到Nacos
      • 1. 初始階段:Eureka單注冊中心環境
      • 2.雙注冊中心階段
      • 3.最終狀态

雙注冊雙訂閱中心

注冊中心遷移

Eureka到Nacos

  • 場景:業務更新,需要将注冊中心從eureka轉到Nacos。nacos功能更強大,響應更快!
  • 要求:需要在不影響業務的情況下完成注冊中心的轉換。即不影響代碼調用的情況下完成注冊中心的替換!!!!

是不是聽着都很高大上!!!

先用文字描述一下整個過程然後開始實操!!

  1. 初始階段。eureka作為注冊中心,provider完成服務注冊并對外提供通路。consumer完成調用provider的相關服務。(consumer可注冊可不注冊,但是需要連接配接注冊中心)
  2. 雙注冊中心階段。用來做過渡
    • 為服務provider上線一個新的執行個體,該執行個體即注冊到eureka又注冊到nacos。provider在eureka有兩個執行個體。
    • 下線舊的provider執行個體,即之注冊到eureka的那個執行個體。這是consumer依舊可以通路到provider存活的另一個執行個體。
    • 為服務consumer上線一個新的執行個體,該執行個體即注冊到eureka又注冊到nacos。consumer在eureka有兩個執行個體。
    • 下線舊的consumer。此時依舊可以使用存活的雙注冊執行個體通路provider服務。
  3. 完成轉換:下線eureka服務中心。使用nacos完成替換。此時可以provider和consumer服務隻和nacos進行互動
  4. 至此完成注冊中心的替換!注意:關于服務之間的調用模式使用ribbon和openFeign都可以。本文以ribbon為例子。

注意:兩個子產品有一個父項目。下邊子產品的依賴省略了父子產品的依賴。父項目pom依賴如下。注意版本間對應關系。如果需要更換版本可以去SpringCloudAlibaba的GitHub上檢視對應關系。位址:https://github.com/alibaba/spring-cloud-alibaba/wiki/版本說明。

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>
	<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
           

1. 初始階段:Eureka單注冊中心環境

provider服務: 9007端口

  1. 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>
        </dependency>
    </dependencies>
           
  1. 配置檔案
server:
  port: 9007
spring:
  application:
    name: aaa
  main:
    allow-bean-definition-overriding: true #當遇到同樣名字的時候,是否允許覆寫注冊
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:6868/eureka
  instance:
    prefer-ip-address: true
           
  1. 啟動類
@SpringBootApplication
public class AApp {
    public static void main(String[] args) {
        SpringApplication.run(AApp.class,args);
    }
}
           
  1. Controller
/**測試網關路由*/
@RestController
@RequestMapping("/demos")
public class DemoController {
    @Value("${server.port}")
    private Integer port;
    @Value("${spring.application.name}")
    private String name;

    @GetMapping
    public String demos(){
        return name+"::"+port;
    }
}
           

consumer服務: 9020端口

  1. 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-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
           
  1. 配置檔案
server:
  port: 9200
spring:
  application:
    name: bbb
  main:
    allow-bean-definition-overriding: true #當遇到同樣名字的時候,是否允許覆寫注冊
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:6868/eureka
  instance:
    prefer-ip-address: true
           
  1. 啟動類
@EnableFeignClients
@SpringBootApplication
public class BApp {
    public static void main(String[] args) {
        SpringApplication.run(BApp.class,args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
           
  1. Controller
@RestController
@RequestMapping("/demos")
public class DemoController {
    @Value("${server.port}")
    private Integer port;
    @Value("${spring.application.name}")
    private String name;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping
    public String demos(){
        String aaa = restTemplate.getForObject("http://aaa/demos", String.class);
        return name+"::"+port+"::"+aaa;
    }
    @GetMapping("/bbb")
    public String demo(){
        return name+"::"+port;
    }
}
           
  1. 檢視eureka的服務狀态
    注冊中心遷移Eureka到Nacos

    aaa和bbb服務各一個執行個體!

    通路http://localhost:9200/demos/

    結果列印:bbb::9200::aaa::9007

2.雙注冊中心階段

一個服務添加為雙注冊雙訂閱中心需要兩步:

1.配置中添加額外配置

spring:
  # 過濾自動化配置類.多注冊中心時需要配置。因為兩者都是SpringCloud規範的解決方案,在注入相應的接口實作類時候會出現沖突。是以需要配置
  autoconfigure:
    exclude: org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration,org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration
           

2.啟動類添加注解

//所有自動注冊服務的實作類在構造過程中都需要該Bean。是以配置使其生效
@EnableConfigurationProperties({AutoServiceRegistrationProperties.class})
           

3.至此這個服務就變成了雙注冊中心雙訂閱的服務。注意:訂閱狀态時需要添加對應注冊中心實作類的Bean,不然不知道注入的是哪個注冊中心的實作類。

@Bean//該Bean聲明是為了指定Ribbon發現服務時确定從那個注冊中心。如果不配置将會報錯說理想需要一個,但是卻發現了兩個
    public ServerIntrospector serverIntrospector(){
        return new NacosServerIntrospector();
    }
           

provider服務:

  1. pom依賴
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
           
  1. 配置檔案
server:
  port: 9008
spring:
  application:
    name: aaa
  main:
    allow-bean-definition-overriding: true #當遇到同樣名字的時候,是否允許覆寫注冊
  # 過濾自動化配置類.多注冊中心時需要配置。因為兩者都是SpringCloud規範的解決方案,在注入相應的接口實作類時候會出現沖突。是以需要配置
  autoconfigure:
    exclude: org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration,org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration
  cloud:
    nacos:
      discovery:
        server-addr: http://localhost:8848/
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:6868/eureka
  instance:
    prefer-ip-address: true
           
  1. 啟動類
@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigurationProperties({AutoServiceRegistrationProperties.class})//所有自動注冊服務的實作類在構造過程中都需要該Bean。是以配置使其生效
//該注解的作用使使用 @ConfigurationProperties 注解的類生效。
public class AApp {
    public static void main(String[] args) {
        SpringApplication.run(AApp.class,args);
    }
}
           
  1. Controller
@RestController
@RequestMapping("/demos")
public class DemoController {
    @Value("${server.port}")
    private Integer port;
    @Value("${spring.application.name}")
    private String name;

    @GetMapping
    public String demos(){
        return name+"::"+port;
    }
}
           

consumer服務: 9021端口

  1. 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-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
           
  1. 配置檔案。
server:
  port: 9201
spring:
  application:
    name: bbb
  main:
    allow-bean-definition-overriding: true #當遇到同樣名字的時候,是否允許覆寫注冊
  autoconfigure:
    exclude: org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration,org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration
  cloud:
    nacos:
      discovery:
        server-addr: http://localhost:8848/
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:6868/eureka
  instance:
    prefer-ip-address: true
           
  1. 啟動類
@EnableFeignClients
@SpringBootApplication
//@EnableDiscoveryClient(autoRegister = false)//是否将該服務注冊到注冊中心
@EnableConfigurationProperties({AutoServiceRegistrationProperties.class})
public class BApp {
    public static void main(String[] args) {
        SpringApplication.run(BApp.class,args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    @Bean//該Bean聲明是為了指定Ribbon發現服務時确定從那個注冊中心。如果不配置将會報錯說理想需要一個,但是卻發現了兩個
    public ServerIntrospector serverIntrospector(){
        return new NacosServerIntrospector();
    }
}
           
  1. Controller
@RestController
@RequestMapping("/demos")
public class DemoController {
    @Value("${server.port}")
    private Integer port;
    @Value("${spring.application.name}")
    private String name;

    @Autowired
    private RestTemplate restTemplate;
//通過使用了Ribbon的RestTemplate模闆通過服務名稱進行RPC遠端調用
    @GetMapping
    public String demos(){
        String aaa = restTemplate.getForObject("http://aaa/demos", String.class);
        return name+"::"+port+"::"+aaa;
    }
    @GetMapping("/bbb")
    public String demo(){
        return name+"::"+port;
    }
}
           
  1. 檢視eureka服務狀态和nacos服務狀态。
    注冊中心遷移Eureka到Nacos
    注冊中心遷移Eureka到Nacos

通路路徑:http://localhost:9021/demos

結果:bbb::9201::aaa::9007 或者bbb::9201::aaa::9008

通路路徑:http://localhost:9020/demos

結果:bbb::9200::aaa::9008 或者bbb::9200::aaa::9007

結論:雙注冊中心已經生效

3.最終狀态

  1. 下線端口為9007的provider服務
  2. 下線端口為9200的consumer服務
  3. 關閉Eureka服務端
  4. 通路http://localhost:9021/demos
  5. 結果:bbb::9201::aaa::9008

    至此注冊中心替換完成,且沒有影響正常代碼的執行,不需要重新開機或者關閉服務就可以實作雙注冊中心做法。

game over!

繼續閱讀