SpringBoot 项目打成 jar 后加载外部的配置文件

ops/2024/12/22 23:08:33/

Spring Boot应用最大的特点就是使用配置来代替编码,很多时候启用某一个功能只需要引入相关的starter,再加入对应的配置项就可以了,例如数据源,安全性,中间件等等。对于单个项目,我们一般会把配置项放到application.property或者application.yaml中,在不同的环境中替换相应的配置值就可以了。但在Spring Cloud项目中,因为引入微服务概念,导致整个系统的服务实例会大大增加,这样如果系统新增了一个配置项,还像以前那样逐个去手工替换配置文件,运维人员估计要累到吐血。而且传统的方式还有一个问题,替换配置文件以后必须要重启整个服务,这对于部分应用来说也是不可接受的。

我们之前在介绍Consul的时候,提到了Consul除了提供服务的注册/发现功能以外,还提供了key/value的存储功能,而且Consul可以提供对存储键值对的CP(强一致性,类似于zookeeper)保证,这样我们就可以利用Consul来实现统一配置中心的相关功能了( Spring Cloud Config 组件也提供基于GIT或SVN的配置中心解决方案)。Spring Cloud 已经为Consul配置中心提供相关的实现框架 — spring-cloud-starter-consul-config。我们只需要在每个服务模块中加入相关的依赖:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>

然后在resources目录中新增一个配置文件bootstrap.yml,用于配置远程配置中心的相关信息:

spring:cloud:consul:host: 192.168.1.220port: 8500discovery:prefer-ip-address: trueconfig:enabled: trueprefix: configdefault-context: applicationprofile-separator: ','data-key: dataformat: yaml

这个bootstrap.yml是spring boot的引导配置文件,其加载优先级高于其它任何配置,是在一个独立的父级上下文(Bootstrap Context)中加载解析的。与配置中心相关的配置都应该放到该配置文件之中,才能够实现初始化应用程序之前先到配置中心去抓取必要的配置。spring.cloud.consul.config的相关配置项意义如下:

enabled: 是否启用consul配置中心
prefix: 配置项在consul中的根目录,默认是config
default-context: 所有服务的公共配置所在的配置目录,默认是application
profile-separator: 配置项目录中profile名称的分隔符,默认是 “,”
data-key:配置项的key名称,默认是data
format:配置项的值的文件格式
比如按照以上的配置,如果spring.application.name设置为order-service,spring.profiles.active为dev的服务启动后默认会去consul的key/value目录的以下四个位置去查找配置信息,配置的key为data,值必须为yaml格式:

config/application,dev/:公共配置信息,profile为dev
config/application/:公共配置信息
config/order-service,dev/:order-service服务的专属配置信息,profile为dev
config/order-service/:order-service服务的专属配置信息
现在我们在order-service服务上测试一下,首先在consul的config/application/和config/order-service/目录分别加入两个配置项:
 

然后添加一个测试的ConfigController ,测试配置项的注入:

@RestController
@RequestMapping("/api/config")
@Slf4j
public class ConfigController {@Value("${global-config.key1}")private String key1;@Value("${service-config.key2}")private String key2;@GetMapping("/test-config-center")public void testConfigCenter() {log.info("global-config.key1:{},service-config.key2:{}", key1, key2);}}
-----------------------------------
springcloud配置文件加载顺序 spring profile active springcloud配置中心consul
https://blog.51cto.com/u_16099298/10397150

访问 http://localhost:9001/api/config/test-config-center 就可以看到控制台输出了对应的配置值:

2020-04-27 11:18:19.505  INFO 15828 --- [nio-9001-exec-9] c.g.d.s.o.controller.Controller          : global-config.key1:value1,service-config.key2:value2

我们再来测试一下配置项的动态更新。为了支持动态更新配置参数,我们需要在注入参数的Spring Component上加入一个@RefreshScope注解,这样才能在参数更新后刷新当前的scope:

 

@RestController
@RequestMapping("/api/config")
@Slf4j
@RefreshScope
public class ConfigController

然后在consul ui中修改配置项的值,将global-config.key1的值修改为:modified-value,保存后再次访问http://localhost:9001/api/config/test-config-center,可以看到控制台打印出的属性值已经是我们修改后的最新的结果了:

2020-04-27 11:45:01.978  INFO 16368 --- [TaskScheduler-1] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-config/order-service/'}, BootstrapPropertySource {name='bootstrapProperties-config/application/'}]
LOGBACK: No context given for c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@2107186835
2020-04-27 11:45:01.992  INFO 16368 --- [TaskScheduler-1] o.s.boot.SpringApplication               : No active profile set, falling back to default profiles: default
2020-04-27 11:45:02.009  INFO 16368 --- [TaskScheduler-1] o.s.boot.SpringApplication               : Started application in 0.694 seconds (JVM running for 70.244)
2020-04-27 11:45:02.150  INFO 16368 --- [TaskScheduler-1] o.s.c.e.event.RefreshEventListener       : Refresh keys changed: [global-config.key1]
2020-04-27 11:45:14.614  INFO 16368 --- [io-9001-exec-10] c.g.d.s.o.controller.ConfigController    : global-config.key1:modified-value,service-config.key2:value2
-----------------------------------
springcloud配置文件加载顺序 spring profile active springcloud配置中心consul
https://blog.51cto.com/u_16099298/10397150

其实配置项的动态刷新是通过不断的轮询Consul的HTTP API,检测相关的配置目录是否发生了变化来实现的,轮询的间隔时间可以通过spring.cloud.consul.config.watch.delay来配置,默认是1000毫秒,如果不想启用自动刷新机制,可以配置spring.cloud.consul.config.watch.enabled=false

本文的相关代码可以查看这里GitHub - davidfantasy/spring-cloud-demo: spring cloud技术体系的实例代码


http://www.ppmy.cn/ops/117247.html

相关文章

Apache Iceberg 与 Spark整合-使用教程(Iceberg 官方文档解析)

官方文档链接&#xff08;Spark整合Iceberg&#xff09; 1.Getting Started Spark 目前是进行 Iceberg 操作最丰富的计算引擎。官方建议从 Spark 开始&#xff0c;以理解 Iceberg 的概念和功能。 The latest version of Iceberg is 1.6.1.&#xff08;2024年9月24日11:45:55&…

php入门

PHP&#xff08;Hypertext Preprocessor&#xff0c;超文本预处理器&#xff09;是一种广泛使用的开源服务器端脚本语言&#xff0c;特别适合用于Web开发&#xff0c;可以嵌入到HTML中。它主要用于创建动态网页&#xff0c;处理表单&#xff0c;管理会话和发送电子邮件等。下面…

【实战篇】到底可不可以使用join?

背景 在实际生产中&#xff0c;关于 join 语句使用的问题&#xff0c;一般会集中在以下两类&#xff1a; 我们 DBA 不让使用 join&#xff0c;使用 join 有什么问题呢&#xff1f;如果有两个大小不同的表做 join&#xff0c;应该用哪个表做驱动表呢&#xff1f; 今天这篇文章…

软件设计-开闭原则

开闭原则是一种重要的设计思想&#xff0c;它为软件系统的可扩展性和可维护性提供了有力的支持。 一、开闭原则的原理 开闭原则&#xff08;Open-Closed Principle, OCP&#xff09;是指软件实体&#xff08;类、模块、函数等&#xff09;应当对扩展开放&#xff0c;对修改关…

C语言⾃定义类型:结构体

目录 前言 1. 结构体类型的声明 1.1 结构的声明 1.2 结构体变量的创建和初始化 1.3 结构的特殊声明 1.4 结构的⾃引⽤ 2.结构体内存对齐 2.1 对⻬规则 实例讲解 2.2 为什么存在内存对⻬&#xff1f; 2.3 修改默认对⻬数 3. 结构体传参 4. 结构体实现位段 4.1 什么…

Springboot Mybatis 动态SQL

动态SQL <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace"com.wzb.SqlImprove2024…

16. C++ TinyWebServer项目总结(16. 服务器调制、调试和测试)

主要包括&#xff1a; 使用 tcpdump 抓包&#xff1b;使用 gdb 调试器&#xff1b;使用压力测试工具&#xff0c;模拟现实世界中的高并发请求&#xff0c;测试服务器在高压状态下的稳定性。 最大文件描述符数 Linux 对应用进程能打开的最大文件描述符数量有两个层次的限制&a…

在CentOS上搭建NFS服务器

环境:CentOS5.2 由于CentOS里面已经装了NFS服务&#xff0c;故不需要安装该服务&#xff0c;只需要进行如下的设置即可&#xff1a; 1、 修改/etc/exports文件&#xff0c;添加如下内容&#xff1a; /home/guochongxin *(rw,sync,no_root_squash) 保存后执行&#xff1a; e…