apolloconfig / apollo

Apollo is a reliable configuration management system suitable for microservice configuration management scenarios.
https://www.apolloconfig.com
Apache License 2.0
29.17k stars 10.2k forks source link

关于SpringCloud的bootstrap阶段PropertySources的建议 #3610

Open magooup opened 3 years ago

magooup commented 3 years ago

你的特性请求和某个问题有关吗?请描述

清晰简洁地描述一下你希望的解决方案

清晰简洁地描述一下这个特性的备选方案

其它背景

test-apollo-2
nobodyiam commented 3 years ago

主要的问题是担心 spring.application.name/server.port 这些值被远端配置覆盖掉? 这个是否还是取决于用户的实际使用情况?一般情况用户不会配置,如果配置的话,是否要看下用户的意图是希望 apollo 的生效还是代码中的生效?

magooup commented 3 years ago

主要的问题是担心 spring.application.name/server.port 这些值被远端配置覆盖掉? 这个是否还是取决于用户的实际使用情况?一般情况用户不会配置,如果配置的话,是否要看下用户的意图是希望 apollo 的生效还是代码中的生效?

@nobodyiam 是这个意思。

我觉得大多数场景用户应该不会有这种自由意图,在项目立项之初,应用名/应用端口应当属于被指定且被约束的,因为这些配置往往会被其他组件/其他系统引用,比如nginx upstream的映射,无注册中心的服务调用等。

结合SpringCloud配置的做法,我猜测它也希望在bootstrap阶段,内置组件初始化注入所需的配置不被扩展配置影响。在重启(故障或手动)动作之后,应用程序启动主流程的行为应当保持一致。

虽然可以通过账户权限限制或者操作行为规范引导用户不做这种配置,但是真的很难保障一定不会出现误操作的情况。比如修改了应用名或端口,一旦此时重启程序,可能会造成一连串的不可预知的内部和外部关联错误。

非Spring项目或者SpringBoot项目不存在这个问题,但是在SpringCloud项目我比较在意这种不可控因素,还是挺希望能与SpringCloud自身的扩展配置机制有一致的行为。不知道是否考虑spring-cloud-config-apollo这样的特定扩展?

nobodyiam commented 3 years ago

SpringBoot项目不存在这个问题

Spring Boot 项目为啥不存在这个问题?spring.application.name/server.port 这些值也是可以配置的

magooup commented 3 years ago

SpringBoot项目不存在这个问题

Spring Boot 项目为啥不存在这个问题?spring.application.name/server.port 这些值也是可以配置的

抱歉,描述不准确。应当是“不存在这个争议”,spring-boot默认只有一个environment,对PropertySource的扩展各家自由度较高(我司common-config扩展了一个优先级更高的constraint.yml(or properties)用于约束固定不可变配置)。

而spring-cloud多了一个bootstrap引导阶段,BootstrapApplicationListener的doc中这样描述:

A listener that prepares a SpringApplication (e.g. populating its Environment) by delegating to ApplicationContextInitializer beans in a separate bootstrap context. The bootstrap context is a SpringApplication created from sources defined in spring.factories as BootstrapConfiguration, and initialized with external config taken from "bootstrap.properties" (or yml), instead of the normal "application.properties".

上述我理解为spring-cloud希望只从bootstrap.properties|yml中读取引导配置,用于初始化spring.factories中指定的BootstrapConfiguration扩展的beans,包含:discovery/cloud-config。对于远程配置中心,在bootstrap.properties配置远程git仓库地址(spring-cloud-config)、nacos server地址(spring-cloud-alibaba-nacos-config),而spring.application.name用于指定git仓库中的子目录(spring-cloud-config)、nacos dataId的组成部分(spring-cloud-alibaba-nacos-config)。对上述远程配置中心,父的bootstrapContext只做了prepare工作,直到子context时才将对应的PropertySource加入。

我司common-config定制之后,对Apollo的使用与上述相同,在bootstrap中只指定meta server地址,用spring.application.name作为优先的namespace,在子context中才将ApolloPropertySources放入envionment,我认为这种方式与spring-cloud-configspring-cloud-alibaba-nacos-config一致,也符合spring-cloud引导阶段的意图。因此才提出希望作者考虑可以在与spring-cloud结合时原生支持上述场景。(方便的做法可以考虑抽离一个单独的项目spring-cloud-config-apollo,扩展BootstrapConfiguration。)

描述不正确的地方请指正。

nobodyiam commented 3 years ago

感谢详细的说明,单独抽离一个项目spring-cloud-config-apollo的话,是指用户引入这个项目后,就不配置apollo.bootstrap.xxx等配置,而改为直接启用 spring cloud config apollo 的配置? 另外,spring cloud 2020.0 开始已经默认禁用 bootstrap了,这块是否会有啥影响?

magooup commented 3 years ago

单独抽离一个项目spring-cloud-config-apollo的话,是指用户引入这个项目后,就不配置apollo.bootstrap.xxx等配置,而改为直接启用 spring cloud config apollo 的配置

是的,是这个效果。

另外,spring cloud 2020.0 开始已经默认禁用 bootstrap了,这块是否会有啥影响?

不好意思之前也没细看2020版本的变化。查了一下,从2020开始SpringCloud默认不再使用bootstrapContext引导启动了,加载configserver只需要这样:spring.config.import=optional:configserver:http://localhost:9000。 如果采用spring-cloud-config-apollo这种方式的话,就要跟随SpringCloud版本的变化而变化了。对于2020.0.x这个版本,要么使用legacy bootstrap兼容方式,要么适配它新的配置中心加载方式(具体我还没看源码😅)。

nobodyiam commented 3 years ago

看了一下相关的源码,单独建一个 spring-cloud-config-apollo 应该也是可行的,不过目前看除了支持BootstrapConfiguration配置外,其它似乎没有看到特别有价值的点?如果要让用户采用一个新的 sdk 的话,可能还需要补充更多的场景进来~