一,背景介绍

      环境: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 的更新

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐