Nacos - Spring Boot - 版本问题记录
nacos-config-spring-boot-starter:0.2.10 及 org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata' that could not be found 引发的“血案”!使用 gRPC 及 NIO 方式替换 HTTP 长连接
一,背景介绍
环境:Docker,JDK-8,gradle,蓝鲸流水线
流程:
打包并上传制品库:gradle 脚本将项目打包成 jar,然后流水线中的 Shell 脚本将 jar,nacos 配置拉取脚本,发布脚本都打包成 zip 包,上传至制品库
发布:发布时,解压 zip 包,执行 nacos 配置拉取脚本,将 nacos 拉取至本地,然后运行 docker run,将应用启动于 docker 中
为何有这篇文章?因为要迁移至 k8s,以上流程在 k8s 中无法获取到配置文件,所以要将 nacos 配置至应用中,在应用启动前就拉取配置文件,从而跟 nacos 配置拉取脚本无关。
由于之前的项目是 Spring Boot 1.5.1 的版本,nacos-spring-boot-starter 版本是 0.1.4 ,将 nacos 相关配置放在应用的 application.yml 中,将 nacos 地址配置到启动变量中,一切相安无事,正常启动,自动刷新等功能均正常。(这里吐槽一下,nacos 0.1.4 竟然是 0.1s 就刷一次接口,而且默认还有日志,太烦了!)
二,问题发现
在处理到其中的一个项目的时候发现,该项目的 Spring Boot 版本是 2.4.3,由于之前有一个项目用的是 Spring Boot 2.1.6,对应 nacos 是 0.2.7 ,然后就照搬过来,启动,报错了
***************************
APPLICATION FAILED TO START
***************************
Description:
Constructor in com.alibaba.boot.nacos.config.binder.NacosBootConfigurationPropertiesBinder required a bean named 'org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata' that could not be found.
Action:
Consider defining a bean named 'org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata' in your configuration.
三,排查尝试
经查询,
org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata
这个类在 Spring Boot 2.4.0 开始就没了,为毛 nacos 还声称 Spring Boot 2.x 对应 nacos 0.2.10!然后找解决方法,一种方法是,从 Spring Boot 2.3.x 中将该类复制过来,然后放在项目中:
然后启动类上加上扫描,同时新增的类要加上 @Component ,让 Spring 容器找到它
诡异的事情发生了!
Caused by: org.springframework.beans.BeanInstantiationException:
Failed to instantiate [com.alibaba.boot.nacos.config.binder.NacosBootConfigurationPropertiesBinder]:
Constructor threw exception;
nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException:
Bean named 'org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata'
is expected to be of type 'org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata'
but was actually of type
'org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata'
需要的类型不匹配!但是我怎么看怎么看,都是一样的,为毛呢?搞不懂。算了,我升高版本,项目的 Spring Boot 版本无法动,那我就升高 nacos 版本到最新的 0.2.10,想着 nacos 应该后续会修复这个问题吧(事后证明,这个也是徒劳)
然后启动,发现这次拿不到配置了,因为 Tomcat 启动端口成了 8080,而不是配置文件中的 9090
调试吧,一步一步调试,过程中发现,nacos 0.2.10 竟然成了 NIO,使用 gRPC 访问的,这给调试带来了很大痛苦(经尝试发现,从 0.2.9 开始由 HTTP 变成了 gRPC),只能看到 errorCode =300, msg = config data not exist,没有其他的有用信息。这时候去官网看了看,按照 nacos 官方的方式,把 application.yml 删了,nacos.config.server-addr 配置在环境中
@NacosPropertySources({@NacosPropertySource(dataId = "common.yml",autoRefreshed = true,groupId = "ci"),@NacosPropertySource(dataId = "application-comment.yml",autoRefreshed = true,groupId = "ci")})
启动的时候,发现,配置能拉取下来了,但是熟悉的画面又出现了:
***************************
APPLICATION FAILED TO START
***************************
Description:
Constructor in com.alibaba.boot.nacos.config.binder.NacosBootConfigurationPropertiesBinder required a bean named 'org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata' that could not be found.
Action:
Consider defining a bean named 'org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata' in your configuration.
WTF ? nacos ,你真的连这个都不修?然后去 GitHub 上看了下,从 2021 年 7 月就有人反馈这个问题了,但是到现在还没有修复!有别的码友支招,除了上面的拷贝这个类之外,就是将 nacos 报错的 NacosBootConfigurationPropertiesBinder 这个类拷贝下来,把里面用到的不存在的类注释掉,然后打包成 jar 包,放在自己项目的 lib 包下。这也是一种解决办法,但是!!这都 21 世纪了!都是 maven 或者 gradle 项目了,nacos 竟然逼着码友们用这种方式去解决问题!
四,最终方案
后续等待 Nacos 的更新
更多推荐
所有评论(0)