Aopllo本地配置覆盖远程配置实现

本文介绍了如何在Spring Boot项目中利用Apollo实现本地配置覆盖远程配置。通过创建一个空的公共namespace `local.properties`,并将其设置为最高优先级,配合Spring的PropertySource机制,可以在无网或离线开发时使用本地`local.properties`文件覆盖远程配置,同时保持对远程配置的复用。这种方式避免了维护完整本地配置的麻烦。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前文
spring-boot:2.1.12
apollo-client: 1.6.0

一、实现本地配置覆盖远程配置实现

  1. Apollo客户端支持本地开发模式,这个主要用于当开发环境无法连接Apollo服务器的时候,这种方式主要用于无网情况下。
    在本地开发模式下,Apollo只会从本地文件读取配置信息,不会从Apollo服务器读取配置。

  2. apollo从4个维度去管理配置,分别是application (应用)、environment (环境)、cluster (集群)、namespace (命名空间)。所以我们可以新建一个专属本地开发的environment 的配置。

这与我设想的要不一样,本地开发模式属于离网模式下的纯本地配置读取。又不想新建environment去管理一份完整的配置。而且开发配置本身就已经建立了一套。

后来无意中发现

Apollo除了支持API方式获取配置,也支持和Spring/Spring Boot集成,集成原理简述如下。

Spring从3.1版本开始增加了ConfigurableEnvironment和PropertySource:

  • ConfigurableEnvironment
    • Spring的ApplicationContext会包含一个Environment(实现ConfigurableEnvironment接口)
    • ConfigurableEnvironment自身包含了很多个PropertySource
  • PropertySource 属性源 可以理解为很多个Key - Value的属性配置

PropertySource之间是有优先级顺序的,如果有一个Key在多个property source中都存在,那么在前面的property source优先

Apollo和Spring/Spring Boot集成的手段就呼之欲出了:在应用启动阶段,Apollo从远端获取配置,然后组装成PropertySource并插入到第一个即可。

于是有了下面这种实现方式:
1、在apollo创建一个公共namespace,比如local.properties,配置为空并发布

进入 Apollo Portal 界面,进入对应的应用,选择新增一个公共的namespace。我这边创建的私有的配置,私有的配置,只会创建在该应用,公共的会在所有应用中。
新增namespace
在这里插入图片描述
在这里插入图片描述

2、应用中引用该公共namespace并确保排序位于其它namespace之前,由于该namespace没有任何配置,所以对应用不会有任何影响。这里我建的是local,所以把local放第一位。

apollo.bootstrap.namespaces = local,application

3、在代码中resources下放一个META-INF/config/local.properties文件,在里面写入要覆盖的配置即可
在这里插入图片描述
配置文件使用本地配置参数。

这样就大功告成了,实现本地配置“覆盖”远程配置。

二、实现的原因

在Apollo中有预埋逻辑,会去尝试读取该文件作为namespace配置的补充。
DefaultConfig.java
在这里插入图片描述
在这里插入图片描述
这种方式是本人最喜欢的方式了。想复用环境的大部分的一些配置,部分配置使用本地的。而不是重新弄一份完整的本地配置。

<think>好的,我现在要解决的问题是YML配置文件与Apollo配置中心之间的优先级对比。用户提到在Spring Boot项目中,遇到了Apollo配置生效的情况,可能因为application-qa.properties的存在,所以想知道YMLApollo的优先级顺序。 首先,我需要回忆一下Spring Boot配置加载的机制。根据引用[2]引用[3],application.properties的优先级高于application.yml,而application.yml又高于application.yaml。这三种都属于本地配置文件,通常在项目的resources目录下。 接下来是Apollo配置中心的优先级。根据引用[1],用户提到Apollo配置优先级低于application的配置。也就是说,当Apollo本地配置文件(如application.yml)中存在相同配置项时,本地配置覆盖Apollo配置。这可能就是用户遇到的qa环境配置生效的原因,因为application-qa.properties中的配置优先级更高,覆盖Apollo的设置。 不过,我需要确认这个结论是否正确。根据Spring Boot的外部化配置原则,配置源的优先级通常由它们的加载顺序决定。Spring Boot允许通过多种方式加载配置,例如命令行参数、JNDI、Java系统属性、操作系统环境变量、配置文件等。而Apollo作为分布式配置中心,通常是通过自定义的PropertySource来集成到Spring环境中。根据Spring的文档,后添加的PropertySource会覆盖先前的。因此,如果Apollo的PropertySource是在应用启动的早期被加载,那么后续加载的本地配置文件(如application.yml)可能会覆盖Apollo配置。 但是,这取决于Apollo客户端的集成方式。例如,如果Apollo在启动时较早地将其配置加载到环境中,那么本地配置文件的加载可能在后面,从而覆盖Apollo的值。反之,如果Apollo配置加载在本地文件之后,则Apollo配置会优先级更高。需要查看Apollo客户端的集成代码或文档,确认其PropertySource的加载顺序。 根据引用[1]中的描述,用户的问题显示Apollo配置优先级低于application配置,这说明Apollo的PropertySource被添加到Spring环境中的顺序可能在本地配置文件之后,导致被覆盖。因此,在默认情况下,如果Apollo配置源在本地配置文件之后加载,则Apollo配置优先级更高;但如果Apollo配置源加载较早,本地配置覆盖它。但根据用户的实际问题,他们的Apollo配置被application-qa.properties覆盖了,说明在用户的环境中,Apollo的优先级确实低于本地配置文件。 总结,在一般情况下,Apollo配置优先级低于本地配置文件(如application.yml),但可能受具体集成方式的影响。需要参考Apollo的官方文档来确认默认行为。如果Apollo配置源在Spring Boot启动过程中被较早地加载,那么本地配置可能会覆盖它,反之则Apollo配置优先级更高。但在用户案例中,由于application-qa.properties的存在,Apollo配置生效,说明本地配置优先级更高。 可能还需要考虑Spring Boot的不同profile配置。例如,application-qa.yml属于特定profile的配置,其优先级可能高于默认的application.yml,但根据引用[2],不同profile的配置优先级可能更高,但总体来说,本地配置文件的优先级仍然高于Apollo。 因此,最终结论是:在Spring Boot项目中,本地配置文件(如application.yml)的优先级高于Apollo配置中心的配置,导致本地配置覆盖Apollo中的相同配置项。但需要注意,实际优先级可能受项目配置Apollo客户端集成方式的影响,建议查阅相关文档或测试验证。</think>在Spring Boot项目中,**YML配置文件(application.yml)的优先级高于Apollo配置中心的配置**,即本地配置覆盖Apollo的相同配置项。以下是具体分析: ### 1. 配置优先级规则 根据Spring Boot的配置加载机制: - **本地配置文件优先级**:`application.properties` > `application.yml` > `application.yaml`[^2][^3]。 - **Apollo配置优先级**:默认情况下,Apollo配置优先级低于本地配置文件(如`application.yml`)[^1]。 ### 2. 验证逻辑 - **本地配置覆盖远程配置**:如果`application.yml`或`application-{profile}.yml`中存在与Apollo相同的配置项,本地配置生效,而Apollo配置将被忽略。 - **典型场景示例**:在QA环境中,若`application-qa.yml`中定义了分库分表配置,即使Apollo中也存在相同配置,最终以本地配置为准。 ### 3. 优先级调整方法 若需要让Apollo配置覆盖本地配置,需通过代码显式调整配置源加载顺序。例如,在Spring Boot启动时,将Apollo的`PropertySource`添加到本地配置之前: ```java // 示例:调整Apollo配置源的加载顺序 public class ApolloConfigInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext context) { ConfigurableEnvironment env = context.getEnvironment(); // 将Apollo配置源插入到默认配置源之前 env.getPropertySources().addFirst(new ApolloPropertySource("apolloSource")); } } ``` ### 4. 实践建议 - **明确配置来源**:优先通过Apollo管理环境相关配置(如数据库连接),而本地配置文件保留不敏感的非环境配置(如服务器端口)。 - **避免重复配置**:同一配置项尽量只在一个位置定义,减少覆盖风险。 - **测试验证**:通过`/actuator/env`端点查看最终生效配置来源。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值