问题场景:
首先介绍一下,问题发现的场景,存在一个项目,在本地开发环境上,spring项目的数据库、redis等中间件的配置参数都是配置在application.yml 文件里的,所以修改配置直接改改文件就可以了,但是当项目部署在k8s的集群上,想要通过修改application.yml文件里的配置项,发现修改无效。
尝试解决
如图,在多次修改application.yml 文件里的连接配置之后,然后发现连接的仍然是修改的之前的配置。
application.yml的配置
运行时的连接
既然,配置无法加载,然后直接写死在Config配置类中,暴力解决
原因分析:
提示:这里填写问题的分析:
例如:Handler
发送消息有两种方式,分别是 Handler.obtainMessage()
和 Handler.sendMessage()
,其中 obtainMessage
方式当数据量过大时,由于 MessageQuene
大小也有限,所以当 message
处理不及时时,会造成先传的数据被覆盖,进而导致数据丢失。
虽然暴力解决了当时的问题,但是毕竟不够优雅。事后,有时间,我考虑了发现这种情况的原因,既然修改不生效,那生效的配置是从何而来,在我一顿操作之后发现,该一直生效的配置是通过K8s的deployment配置的。问题到了这里,就出现了一个新的问题,那就是为什么k8s的配置生效了,application的配置没有生效。理由很简单,就是配置优先级问题。
Spring boot 配置优先级
Spring Boot使用一个非常特殊的PropertySource顺序,该顺序旨在允许对值进行合理的重写。后来的属性源可以覆盖早期属性源中定义的值。默认顺序如下:
参考:Spring官方文档:
- 默认属性(通过设置SpringApplication.setDefaultProperties指定)。
- @PropertySource在您的@Configuration类上的注释。请注意,在刷新应用程序上下文之前,不会将此类属性源添加到环境中。现在配 置某些属性(如logging.和spring.main.)已经太晚了,这些属性在刷新开始之前被读取。
- 配置数据(如application.properties文件)。
- 仅具有随机属性的RandomValuePropertySource。*。
- OS环境变量。
- Java系统属性(System.getProperties())。<