启动脚本命令行参数失效
在一次应用发布的过程中,运维表示 –server.port=8080未生效,监听到的端口并不是8080,导致健康检测失败,应用不断重启。
这时候就感觉很奇怪了,因为在SpringBoot中,命令行参数的优先级应该是最高的。
在继续找问题的时候,发现我们使用的配置中心Apollo中设置了 server.port=8138 这个配置。 所以怀疑是否是Apollo将 SpringBoot 的配置进行了覆盖。
在 debug 启动应用后,我们可以看到 Apollo 的配置优先级最高。
这就说明了 Apollo 做了一些扩展。Apollo 在下面两个地方进行了扩展。
- ApolloApplicationContextInitializer
- PropertySourcesProcessor
在 ApolloApplicationContextInitializer 中将 Apollo 的配置的优先级设置为最高。 PropertySourcesProcessor 也有类似的操作,不过 PropertySourcesProcessor 是为了给非SpringBoot应用设置的。
解决方法
那么Apollo的优先级最高,如何在启动脚本中设置能够设置参数覆盖Apollo的配置呢。 方法是 -D 参数。 比如设置 -Dserver.port=8080 就能覆盖 Apollo 的配置。
我们可以看到在 Apollo 的 DefaultConfig 中, 是先获取 Java 应用的属性配置和环境变量。再去获取Apollo的配置。
注
不光 Apollo 会做这样的事情,SpringCloudConfig 也会做相同的事情,但是 SpringCloudConfig 有参数可以设置不覆盖Java系统参数,这样就会将配置中心的配置放到 SystemEnvironment 之后。这样优先级就会降低。