背景
项目springboot 2.x 配置了双配置中心nacos及consul。问题:发现修改的时候无法动态更新,这样导致新做的在线开关功能无法实现开启和关闭,也不符合原来配置中心的作用。相关版本信息如下:
组件名称 | 版本号 | 备注 | |
---|---|---|---|
springboot | 2.2.7.RELEASE | ||
spring-cloud-starter-alibaba-nacos-config | 2.2.7.RELEASE | ||
spring-cloud-starter-alibaba-nacos-discovery | 2.2.7.RELEASE | ||
spring-cloud-starter-consul-config | 2.2.2.RELEASE | ||
spring-cloud-starter-consul-discovery | 2.2.2.RELEASE |
排查过程
1、与其他能同步的项目进行对比,发现springcloud项目同样的配置,但是可以同步刷新,但是该项目不行;
2、查看修改后的nacos本地配置文件和日志发现,配置中心修改后的本地没有拉取并且项目中日志没有同步(核心原因);
服务本地文件
nacos配置
consu没有配置。
因为是双注册中心,所以consul会不会可以通讯呢?然后再验证一下consul的配置,发现consul上面其实没有配到,这里发现其实双注册中心中,如果一个配置中心不配置,另外一个配置,那会以有的为主。
其实到这里已经知道核心原因就是没有拉取到,但是因为版本不兼容的原因导致没有拉取?还是因为缺少jar包或者说配置有问题?
然后通过:
https://nacos.io/zh-cn/docs/quick-start-spring-boot.html nacos配置中心的springboot
https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html nacos配置中心的springcloud
规范进行配置,springboot和springcloud。
代码语言:javascript复制@Configuration
@RefreshScope
public class NaconsCommonValueConfig {
@Value("${udeskapicontrol}")
private String Control;
@NacosValue(value = "${udeskapicontrol}", autoRefreshed = true)
private String api;
public String getControl() {
return ApiControl;
}
public void setControl(String Control) {
this.Control = Control;
}
public String getApi() {
return api;
}
public void setApi(String api) {
this.api = api;
}
}
然而发现其实都没有生效~...这时候陷入迷漫中....版本信息、配置以及相关的信息都与官网的一些难道官网有错。
3、重新拉新项止目测试,发现官网提供的demo是可以拉取的。(确认是自身项目原因);
4、因为版本不兼容的原因导致没有拉取?还是因为缺少jar包或者说配置有问题?,上面说的这几种说法都有验证没有关系,那是通讯问题?
关于这个问题其实首先要了解一下 nacos客户端和服务端的通讯区别,这个的话详细看:https://nacos.io/zh-cn/docs/what-is-nacos.html
通过以上架构和nacos的说明得知,nacos客户端有一个监听,检查服务端的配置信息是否发生了变化,如果发生变化则触发通知进行变更。(可以参考底层实现)
问题解决
看了系统日志发现,这个监听其实不生效了,因为有consul nacos 还有其他的一些组件,可能导致各种各要的协调冲突,通过spring官网发现。https://docs.spring.io/spring-cloud-bus/docs/2.2.4.RELEASE/reference/html/
cloud-bus可以做为协调统一消息总线进行协作,引入相关的配置验证,发现还真是。而springcloud alibaba默认引入了:spring-cloud-starter-netflix-hystrix 里面的Stream 承担了消息总线类似的功能(个人认为)
配置如下:
引入bus组件
代码语言:javascript复制 <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
配置文件中加入
#spring.application.name 为项目名称
#spring.cloud.config.profile 为项目环境
代码语言:javascript复制spring.cloud.bus.id=${spring.application.name}:${spring.cloud.config.profile}
修改前:
修改配置文件:
更新配置文件,发现项目更新也进行更新。
修改后,动态生效;
问题解决~
通过查询相关的资料发现,spring cloud alibaba项目中已经集成了类似消息总线的组件,而spring boot如果不引用其他中间件,只是引用了原官方文档是可以使用,但是比如引用了mq 多配置中心还有其他组件,各种组件协调可能会引发冲突会失效配置。虽然代码没有报错,但是在日志提示中也是可以看到有一些warn这些虽然无关紧要,但是一但不细心真的就错过解决问题的核心点。
参考文章:
https://www.cnblogs.com/wuzhenzhao/p/11385079.html
https://docs.spring.io/spring-cloud-bus/docs/2.2.4.RELEASE/reference/html/