本文正在参加「金石计划 . 分割6万现金大奖」
小伙伴们好呀,今日来填一下这个坑 —— 将注册中心从 Eureka 搬迁到 Nacos
这儿边涉及到这个 双注册双订阅形式 ,下面让咱们一起看看叭~
首先,为啥要搬迁呢?
主要是它对比其他注册中心,现已落后太多了
- 就拿 Nacos 来说吧,不仅有 装备中心,管理界面,还能手动上下线,并且支撑服务列表改动的消息推送形式(实时性高)
- Eureka 1.x 的架构有些地方能够改进,比方 在客户端的 pull 形式下,添加这个消息推送形式,添加实时性;还有 集群,Eureka 只支撑 AP ,各个客户端都能进行写恳求✍ , 没有主从节点之分,各个节点之间经过相互仿制来同步数据,无法保证一致性。Nacos 则有 AP 和 CP 两种挑选,更灵活。
- 2019年的某个会上,Spring 团队提出怎么处理 Netflix 进入保护形式后的 SpringCLoud 组件挑选问题。
- 便是 Eureka 早已进入保护形式啦!并且 long long ago ,官方就放弃了这个 Eureka2.X 版别的开发(看了下分支,6,7年前的代码了),并且官方还说了不能用在生产上,后果自负(额 咱也不知道它有啥新特点,反正 SpringCloud 一直用的 1.x 版别。现在更新到1.10 了)
简单了解了这个背景后,咱们再来看看 4ye 建立的这个 demo
Eureka 注册中心
比方 老项目中,运用的注册中心是 Eureka 。架构如下
代码也很简单,有三个模块。分别是
- 注册中心 : 建立时挑选 Eureka Server 即可。
- 服务供给者(provider): 建立时挑选 Eureka Discovery Client 和 Spring Web 即可。
- 服务消费者(consumer):建立时挑选 Eureka Discovery Client 和 Spring Web 即可。
然后顺次发动注册中心,provider,consumer 即可。
拜访 http://localhost:8772/hello/Java4ye 能够看到下面的内容。
双注册双订阅形式
接着,咱们克隆上面的 provider 和 consumer 模块。
在 pom 文件中直接加入 Nacos 和 Eureka 。
发动时会抛出下面的异常信息 。(引进 Actuator 时会呈现另一个,相同排除去即可)
Description:
Field autoServiceRegistration in org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration required a single bean, but 2 were found:
- nacosAutoServiceRegistration: defined by method 'nacosAutoServiceRegistration' in class path resource [com/alibaba/cloud/nacos/registry/NacosServiceRegistryAutoConfiguration.class]
- eurekaAutoServiceRegistration: defined by method 'eurekaAutoServiceRegistration' in class path resource [org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.class]
能够看到是主动安装时,不知道用哪个导致的异常。可是咱们两个都要
这儿只要在 application.properties 中把这个主动安装移除去即可。
# 双注册形式下封闭
spring.autoconfigure.exclude=org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration,org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration
当然,秉着严谨的态度,咱们在这两个类中打入相应的断点,能够看到他们都被创建了。
同时,也成功注册到这两个注册中心去了
这个时分,再次拜访旧的客户端 8772 端口的,能够发现如下作用。
可是要注意,此刻项目的架构变成这样,consumer 中只要 Eureka 的客户端,所以调用到的都是 Eureka 中心中的服务。此刻流量不会走到 Nacos 这边
接着便是看客户端 consumer 正不正常,比方跑个一天看看。
安稳后,下一步便是 下线这个 provider ,然后看看正不正常了。相同安稳后,便是预备发动这个 双订阅的客户端了。
小试验
可是我这儿做了一个小试验 哈哈 想看看不下线的状况,我这个 新客户端 上线后是运用哪个注册中心的服务多点。
所以,接着,咱们就发动这个新的 consumer,一个双订阅的客户端。
相同修正下装备文件即可。
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
# Nacos 服务发现与注册装备,其中子特点 server-addr 指定 Nacos 服务器主机和端口
spring.cloud.nacos.discovery.server-addr=192.168.175.128:8848
# 注册到 nacos 的指定 namespace,默认为 public
spring.cloud.nacos.discovery.namespace=public
# 双注册形式下封闭
spring.autoconfigure.exclude=org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration,org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration
这个时分,咱们拜访新的客户端。8872 端口的: http://localhost:8872/hello/Java4ye
发现无论怎么刷新,接口的返回值都是下面这个,无法达到负载均衡的作用 。 (⊙o⊙)?
简单翻看了下源码,能够发现体系创建了三个 discoveryClient ,最终一个是兜底用的。
并且 nacos 排在第一个,这意味着从 nacos 的注册中心中找到服务的话,就不会调用到 Eureka 中的了。
了解了这个原理后,将 nacos 中的服务进行下线。
然后去刷新新的客户端,8872 端口的,能够发现,又呈现了负载均衡的作用了。
并且得益于 Nacos 的服务列表改动推送机制,咱们客户端能够实时感知到 服务列表的 改动,这个时分直接去刷新新客户端的接口,能够发现它现已切换到 Eureka 中了,没有推迟感!
所以当咱们在搬迁的过程中,假如发现 Nacso 上新的 provider 有什么异常时,能够将其下线先 悄悄一点真的太方便了
高雅下线
完毕上面的小试验,回到正常流程中,咱们要来下线这个 provider 了。
这儿就得考虑这个 高雅下线 的问题了。
网上的方案许多,这儿用 Springboot 的 actuator 来完成。
这个 graceful 装备是 Springboot2.3 之后才有的,会让内嵌服务器拒绝外部恳求,然后处理完现已在内部的恳求后,进入封闭状况。
经过这个暴露的 api,去修正 eureka 中 service 的状况。
# 高雅下线
server.shutdown=graceful
# 封闭超时
spring.lifecycle.timeout-per-shutdown-phase=20s
#
management.endpoints.web.exposure.include= service-registry
这儿直接拜访 curl “localhost:8771/actuator” 来获取咱们注册的这个 API (能够看到咱们 – 符号被吃掉了 坑)
接着,咱们经过这串恳求,改动 Eureka 中服务的状况: DOWN。
curl -X "POST" "http://localhost:8771/actuator/serviceregistry?status=down" -H "Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8"
然后,在等待若干时间后,应该是客户端 consumer 重新去拉取服务列表信息后。(哈哈 我没数)
不过我配了 10s ,然后咱们不断刷新恳求,会发现这个负载均衡的作用现已消失了。只剩新的 provider 供给的服务了
然后在服务安稳一段时间后,能够经过 Prometheus 来观察这个旧的 provider 的 qps 等,当它现已没有啥流量进入了,便能够直接封闭下线了。( kill -9)
上线双订阅客户端
接着,上线这个 新的 consumer ,这儿也没啥特别的了。
相同等体系安稳后,下线这个旧的客户端 consumer 了。
并且从上面小试验环节中,咱们能够知道流量会先来到这个 Nacos 中,确认里边没有这个服务的话,才去这个 Eureka 中查找。所以到这儿,这个 Eureka 中的流量就会少了大部分了。
再次上线
到了这儿,咱们还不能直接封闭这个 Eureka,还得再次上线新版别的只要 Nacos 注册中心的 provider 和 consumer
这次的新版要注意这个负载均衡,咱们去掉了 Netflix 后,得手动引进 SpringCloud 的 loadbalancer 组件。其他也就删删装备了。
相同的,安稳后,才去下线双订阅客户端 consumer,再下线双注册服务端 Provider,最终才下线这个 Eureka。
这儿经过 Nginx 等去控制流量,将他们打到新的只订阅 Nacos 的 consumer 上,最终等双订阅的 consumer 客户端没啥流量就给它下线了。
接着,在 Nacos 上 ,下线那个双注册的服务,然后再去下线它。
最终就直接封闭 Eureka 了。
这样就完成了这个注册中心的搬迁了
整体流程
这儿其实便是上线新版别后,等其安稳,下线旧版别的一个规矩。
关于应用的发布,这儿就不多赘述了,网上大把的 蓝绿发布,灰度发布,还有 K8s 的 pod 容器,docker 等环境下的决议计划。
最终
github.com/Java4ye/spr…
整个demo 我也弄到 GitHub 上啦,新开的坑 哈哈,后面也会逐步完善的
觉得不错的话,能够 Star 支撑一波哦
总结
经过本事例,能够快速了解到这个搬迁过程中:
- 这个代码根本都没改!这得益于这个 SpringCloud 的统一服务注册和发现的编程模型
- 运用双注册双订阅模型时,要排除去主动安装的坑,并且在这个形式下,流量根本都跑到 Nacos 这边。
- 对比下两个注册中心,更能感觉到 Nacos 这么多便利的功用:上下线和服务列表改动的推送机制。
- 了解到 Springboot 在高雅下线这一块做的改动,谨记不要容易 kill -9!