1.背景
Nacos與Eureka相比,Nacos的優點非常明顯,當然首選Nacos作為注冊中心。本文主要介紹如何從Eureka無縫平滑遷移到Nacos注冊中心,業務方應用改動最小,業務應用改造一次完成遷移。
2.方案設計
2.1 業務應用多注冊到Nacos和Eureka
Spring Cloud應用默認不支持啟動時雙向注冊,但是阿里商業版上雲edas-sc-migration-starter組件支持。可以采用如下的方式引入依賴實現多注冊和訂閱。
<!-- https://mvnrepository.com/artifact/com.alibaba.edas/edas-sc-migration-starter --> <dependency> <groupId>com.alibaba.edas</groupId> <artifactId>edas-sc-migration-starter</artifactId> <version>1.0.2</version> </dependency>
也就是引入對應的組件,當應用啟動的時候同時向Eureka和Nacos實現雙向注冊。更多的實現細節和使用細節本文將不進行展開。
如上圖所示,如果只把舊應用只改一部分,會出現只有改造的應用能調到新應用。未改造的應用會出現調不到新應用的情況。即,需要如下圖所示的方式,舊應用全部升級改造為雙注冊到注冊中心,才可以支持。
但是舊應用無法保證同一時刻全部升級改造為同時注冊,因此該方案論證失敗。
2.2 Nacos Sync方案
Nacos Sync 是一個支持多種注冊中心的同步組件,基於 SpringBoot 開發框架,數據層采用 Spring Data JPA,遵循了標准的 JPA 訪問規范,支持多種數據源存儲,默認使用 Hibernate 實現,更加方便的支持表的自動創建更新。但目前最新版本是如下圖所示。
2.3 注冊中心服務端雙向同步
2.3.1 方案設計
設計思路是注冊中心服務端進行雙向同步,做到微服務端完全無侵入,可以隨業務迭代逐步完成升級和遷移。改造Eureka Server,Eureka Server引入同步組件實現Nacos和Eureka之間實現雙向同步,如下圖所示:
2.3.2 遷移步驟
遷移步驟如下:
-
1.部署Nacos Server集群用於服務注冊與發現
-
2.在線動態擴容Eureka Server,替換其中的1-2兩台Eureka Server。
-
3.逐漸改造舊應用,只需將新舊應用注冊到Nacos上
-
4.等舊應用全部改造完畢,下線Eureka Server即可。
這樣方案的優點,如下:
-
1.新應用直接注冊到Nacos上,不需要同時注冊到Eureka和Nacos上
-
2.舊應用直接改造(引入相關starter即可)注冊到Nacos上即可,不需要同時注冊到Nacos和Eureka上
-
3.遷移成本很低,舊應用只需改造一次(所謂的改造即引入新的Starter,修改配置),等全部舊應用遷移完畢,直接下線Eureka Server。
3.遷移落地
3.1 組件開發
開發一個Spring Boot Starter,加入到Eureka Server或Nacos Server中可以實現雙向注冊。
3.2 spring-cloud-nacos組件介紹
-
spring-cloud-nacos主要由
何鷹和瞿禮
貢獻, -
Nacos Plus在Nacos上做加法,Nacos client默認是支持安全控制的可以參考阿里雲商業版配置中心ACM集成方式
https://github.com/alibaba/spring-cloud-alibaba/wiki/ACM 以及 spring cloud alibaba 配置項
https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme-zh.md 但是開源的Nacos並不含有安全控制模塊,在Nacos plus里我們新增了兼容默認Nacos client的安全控制功能。
備注: 可以查看:https://github.com/inacos/nacos
核心代碼主要是NacosSynchronizer.java和EurekaSynchronizer.java,請自行閱讀。 github地址:https://github.com/inacos/spring-cloud-nacos
4.實現遷移落地
按如下,遷移步驟進行遷移。具體細節在本文省略。 1.部署Nacos Server集群用於服務注冊與發現 2.在線動態擴容一台Eureka Server 3.逐漸改造舊應用,只需將新舊應用注冊到Nacos上 4.等舊應用全部改造完畢,下線Eureka Server即可。
下面將在本地進行測試說明,用到的演示說明列表如下所示:
服務 | 說明 |
---|---|
Eureka注冊中心(http://eureka.springcloud.cn/) | 模擬生產上的Eureka注冊中心 |
本地基於源碼方式啟動一個Nacos實例 | 模擬生產上新建的Nacos |
同步服務(本地基於Eureka Server擴展啟動的同步服務) | 模擬生產上啟動了一個Nacos與Eureka之間雙向同步的服務 |
本地啟動一個服務注冊到(http://eureka.springcloud.cn/) | 驗證從eureka同步服務到nacos |
本地啟動一個服務注冊到Nacos | 驗證從nacos同步服務到Eureka上 |
4.1 模擬生產上的注冊中心
Spring Cloud中國社區公網上有個Eureka注冊中心,地址為:http://eureka.springcloud.cn/
4.2 基於源代碼方式啟動Nacos
基於Nacos的最新Master代碼,本地IDEA設置環境變量-Dnacos.standalone=true,啟動Nacos,如下所示:
2.打開瀏覽器訪問 http://localhost:8848/nacos/index.html,輸入用戶名和密碼(均為nacos)登錄。
4.3 啟動同步服務測試
4.3.1 搭建同步服務
1. 示例工程如spring-cloud-nacos-eureka-proxy-example所示,在一個Eureka Server中引入如下的pom依賴:
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- 引入Nacos與Eureka之間同步的Starter <dependency> <groupId>net.nacos</groupId> <artifactId>spring-cloud-nacos-eureka-proxy</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>1.1.3</version> </dependency> </dependencies>
2. 在application.properties配置如下信息
server.port=8761
spring.application.name=eureka-proxy
spring.cloud.nacos.discovery.serverAddr=localhost:8848
eureka.client.serviceUrl.defaultZone=http://eureka.springcloud.cn/eureka/
#eureka.client.fetchRegistry=false
#eureka.client.registerWithEureka=false
eureka.instance.preferIpAddress=true
eureka.server.enable-self-preservation=false
4.3.2 啟動服務
啟動同步服務,訪問Nacos頁面發現已經把Eureka上面的服務同步到Nacos,如下所示:
說明,因為是從公網Eureka上同步過來的服務列表,部分服務不在本地。因此Naocs將會從服務列表中踢除。但不影響驗證功能。
4.3.3 驗證從Eureka同步到Nacos
啟動一個moss-sample-2.1.x的服務只注冊到 http://eureka.springcloud.cn/,立即同步到Nacos上,可以自行驗證。
4.3.4 驗證從Nacos同步到Eureka
啟動一個服務一個服務只注冊到Nacos上,發現立即同步到 http://eureka.springcloud.cn/上,如下圖所示:
5.總結
本文從遷移的方案入手,進行論證如何將注冊中心從Eureka遷移到Nacos。如何在遷移的過程中有任何疑問,歡迎溝通交流。