m0_59661148 2025-01-12 03:34 采纳率: 100%
浏览 46
已结题

Spring Cloud整合Consul KV功能启动报错,如何解决?

Spring Cloud整合Consul KV功能启动报错
先介绍项目的基本版本情况:spring-boot-starter-parent:2.6.6,spring-cloud-dependencies:2021.0.9,spring-cloud-starter-consul-config在pom文件中引入时没有指定版本,具体版本由它的parent管理,向上追溯为spring-cloud-dependencies-parent:3.1.9。
假设配置文件在Consul KV中的路径是config/serviceA-dev/serviceAConfig,在其中一个微服务配置好spring.cloud.consul.config.*相关参数之后,如果只需要引入这个config/serviceA-dev/serviceAConfig文件,那么spring.config.import的值直接写 'consul:' 项目即可正常启动。
但问题是实际项目中极大概率是一个服务通常需要引入多个配置文件,尤其是设计公共配置和私有配置的情况下,此时在spring.config.import后面追加一个consul:config/serviceB-dev/serivceBConfig,可能出现两种情况:

  1. 如果配置中指定了Consul服务的IP端口,代码中通过@Value注入的、存在于serviceAConfig中的配置项会找不到,报错Could not resolve placeholder 'placeholder' in value "${placeholder}";
  2. 如果配置中未指定Consul服务的IP端口,启动时会报错:Config data resource '[ConsulConfigDataResource@f2c488 context = '/serviceB-dev/serivceBConfig/', optional = true, properties = [ConsulConfigProperties@54acff7d enabled = true, prefixes = list['config'], defaultContext = 'serviceA', profileSeparator = '-', format = YAML, dataKey = 'serviceAConfig', aclToken = 'placeholder', watch = [ConsulConfigProperties.Watch@5488b5c5 waitTime = 55, enabled = true, delay = 10000], failFast = true, name = 'application'], profile = [null]]' via location 'consul:config/serviceB-dev/serivceBConfig' does not exist

网上关于整合Consul作为配置中心的帖子和开源项目都只引入了一个配置文件,而且要么SpringBoot版本较低没遇上,要么遇到引入外部配置源必须写spring.config.import的问题好多都是加个配置直接绕过,请问有没有遇到过类似问题的?到底应该怎么解决?

  • 写回答

5条回答 默认 最新

  • m0_59661148 2025-01-14 16:39
    关注

    20250114补充:

    1. Consul服务确认运行正常;
    2. Consul服务中对应路径下配置文件存在,文件中对应的配置项存在且格式正确;
    3. 配置文件中指定的acl-token是agent token,但已经配置相应权限,并且即使切换为master token也会报同样的错误,所以不是权限原因;
    4. 如果将多个配置文件写在一行中,并用“,”分隔,启动时会报错:Config data resource ... via location 'consul:config/serviceA-dev/serviceAConfig,optional:consul:config/serviceB-dev/serviceBConfig' does not exist;

    20250210补充:

    • 在主启动类中将所有配置源通过 org.springframework.core.env.ConfigurableEnvironment#getPropertySources 获取并遍历输出后发现,在spring.config.import中引入的consul配置源末尾总是会追加斜杠“/”,也就是 /config/serviceA-dev/serviceAConfig/
      ,这种情况下serviceAConfig并非配置文件key,而是被视为了配置文件路径,这与spring.config.import内部逻辑有关,但我追踪之后并未找到具体位置。

    • 如果将spring.config.import的值改为 "consul:" ,并在spring.cloud.consul.config.*相关配置项中拼接配置文件路径,查看consul源码可以发现,用于指定配置文件key的spring.cloud.consul.config.data-key只接收一个参数,高版本spring-cloud-starter-consul-config依赖可以使用spring.cloud.consul.config.prefixes配置多个配置文件前缀路径,而低版本中只能使用spring.cloud.consul.config.prefix接收一个前缀路径,所以即使使用高版本consul,最终拼接出的多配置文件结果也应该是多个不同路径下拥有相同key的配置文件,如 /config/serviceA/serviceConfig、/config/serviceB/serviceConfig 等,这样的配置文件命名规则似乎不太符合一般命名逻辑,至少不能通过配置文件名进行功能划分。

    • 目前通过AI建议、查询GitHub等方式找到的资料中,未发现基于前文中描述版本的切实可行的多配置文件引入方案,只能暂时得出结论:Consul提供的KV Store功能对于将所有配置项集成到一个配置文件的服务中可以使用,但涉及到多配置文件引入时不够灵活,用来作为服务注册与发现组件即可,作为配置中心反而可能增加开发难度和学习成本。

      欢迎实测可行的方案交流

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 3月20日
  • 已采纳回答 3月12日
  • 修改了问题 1月12日
  • 创建了问题 1月12日