如何让Spring Boot 的配置 “动” 起来?
前言
对于微服务而言配置本地化是个很大的鸡肋,不可能每次需要改个配置都要重新把服务重新启动一遍,因此最终的解决方案都是将配置外部化,托管在一个平台上达到不用重启服务即可一次修改多处生效
的目的。
但是对于单体应用的Spring Boot项目而言,动态刷新显然是有点多余,反正就一个服务,改下重启不就行了?
然而在某些特殊的场景下还是必须用到动态刷新的,如下:
添加数据源
:对接某个第三方平台的时候,你不可能每次添加一个数据源都要重启下服务固化的对接
:大量的固定对接方式,只是其中的某个固定的代码段不同,比如提供视图中的字段不同,接口服务中字段不同等情况。
当然以上列举的两种场景每个公司都有不同的解决方案,这里不做深究。
微服务下有哪几种主流的方案?
微服务下的动态配置中心有三种主流的方式,如下图:
上图中的三种配置中心方案可以说是现在企业中使用率最高的,分别是:
Nacos:阿里巴巴的最近开源的项目,这个家伙很牛逼,一个干掉了
Eureka
(停更)和Config+Bus
,既能作为配置中心也能作为注册中心,并且有自己的独立的 管理平台,可以说是现在最主流的一种。Config+Bus:早期在用的微服务配置中心,可以依托
GitHub
管理微服务的配置文件,这种现在也是有不少企业在用,但是需要自己独立部署一个微服务,和Nacos
相比逊色了不少。Apollo:携程开源项目Apollo,这个也是不少企业在用,陈某了解的不多,有兴趣的可以深入研究下。
针对Spring Boot 适用的几种方案?
其实上述三种都可以在Spring Boot项目中适配,但是作为单体应用有些重了,下面作者简单的介绍两种可用的方案。
Spring Boot+Nacos(不推荐)
不得不说阿里巴巴确实挺有野心,阿里要做的其实是一个微服务生态,Nacos不仅仅可以作为Spring Cloud的配置和注册中心,也适配了Dubbo、K8s,官方文档中对于如何适配都做了详细的介绍,作者 这里就不再详细介绍了,如下图:
当然Nacos对Spring、Spring Boot 项目同样适用。
如何使用呢?这里作者只提供下思路,不做过多的深究,这篇在作者下个专栏Spring Cloud 进阶会详细介绍:
下载对应版本的Nacos,启动项目,访问
http://localhost:8848
进入Nacos的管理界面;Spring Boot 项目引入Nacos的配置依赖
nacos-config-spring-boot-starter
,配置Nacos管理中心的地址。@NacosPropertySource
、@NacosValue
两个注解结合完成。
@NacosPropertySource
:指定配置中心的dataId
,和是否自动刷新@NacosValue
替代@Value
注解完成属性的自动装配
如果公司项目做了后台管理,则可以直接调用Nacos开放的API修改对应配置的值(替代了Nacos管理界面的手动操作),API的地址:https://nacos.io/zh-cn/docs/open-api.html
此种方案虽说可以实现配置的动态刷新,但是还要集成Nacos,启动一个Nacos的服务,完全是有点大材小用了,实际项目中不推荐使用。
Spring Boot+Config+actuator(推荐)
此种方案实际使用的是Config配置中心,但是不像Nacos那般重,完全适用于单体应用的SpringBoot项目,只需要做小部分的更改即可达到效果。
方案一(不推荐)
添加Config的依赖,如下:
<!-- springCloud的依赖-->
<dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Hoxton.SR3</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement><!-- config的依赖-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency><!-- actuator的依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
配置文件中暴露Spring Boot的端点,如下:
management.endpoints.web.exposure.include=*
配置文件中新增三个属性配置:
config.version=22
config.app.name=dynamic-project
config.platform=mysql
结合
@RefreshScope
注解动态刷新,写个Controller,如下:
@RestController
//@RefreshScope该注解必须标注,否则无法完成动态更新
@RefreshScope
public class DynamicConfigController {@Value("${config.version}")private String version;@Value("${config.app.name}")private String appName;@Value("${config.platform}")private String platform;@GetMapping("/show/version")public String test(){return "version="+version+"-appName="+appName+"-platform="+platform;}
启动项目测试,浏览器访问
http://localhost:8080/show/version
,返回信息如下图:
修改
target
目录下的配置文件,如下:
config.version=33
config.app.name=dynamic-project
config.platform=ORACLE
POST请求
http://localhost:8080/actuator/refresh
接口,手动刷新下配置(必须,否则不能自动刷新)浏览器再次输入
http://localhost:8080/show/version
,结果如下图:
可以看到,配置已经自动修改了,结束。
方案二(推荐)
看到了方案一觉得如何?是不是有点鸡肋了
第一个问题:为什么还要调用一次手动刷新呢?
第二个问题:只能手动的在配置文件中改吗?如果想在后台管理系统改怎么办?
想要解决上述两个问题还是要看下Config
的源码,代码关键部分在org.springframework.cloud.context.refresh.ContextRefresher#refresh()
方法中,如下图:
因此只需要在修改属性之后调用下ContextRefresher#refresh()
(异步,避免一直阻塞等待)方法即可。
为了方便测试,我们自己手动写一个refresh接口,如下:
@GetMapping("/show/refresh")public String refresh(){//修改配置文件中属性HashMap<String, Object> map = new HashMap<>();map.put("config.version",99);map.put("config.app.name","appName");map.put("config.platform","ORACLE");MapPropertySource propertySource=new MapPropertySource("dynamic",map);//将修改后的配置设置到environment中environment.getPropertySources().addFirst(propertySource);//异步调用refresh方法,避免阻塞一直等待无响应new Thread(() -> contextRefresher.refresh()).start();return "success";}
上述代码中作者只是手动设置了配置文件中的值,实际项目中可以通过持久化的方式从数据库中读取配置刷新。
下面我们测试看看,启动项目,访问http://localhost:8080/show/version
,发现是之前配置在application.properties
中的值,如下图:
调用refresh
接口:http://localhost:8080/show/refresh
重新设置属性值;
再次调用http://localhost:8080/show/version
查看下配置是否修改了,如下图:
从上图可以发现,配置果然修改了,达到了动态刷新的效果。
总结
本文从微服务的配置中心介绍到Spring Boot 搭建简易的配置中心,详细介绍了几种可行性的方案,作者强力推荐最后一种方案,简化版的Config
,完全适用于单体应用。
如何让Spring Boot 的配置 “动” 起来?相关推荐
- Spring Boot 属性配置和使用
spring Boot 允许通过外部配置让你在不同的环境使用同一应用程序的代码,简单说就是可以通过配置文件来注入属性或者修改默认的配置. Spring Boot 系列 Spring Boot 入门 S ...
- springboot原生mysql写法_【Rainbond最佳实践】Spring Boot框架配置MySQL
Rainbond开源软件介绍: Rainbond是国内首个开源的生产级无服务器PaaS. 深度整合基于Kubernetes的容器管理.多类型CI/CD应用构建与交付.多数据中心的资源管理等技术,提供云 ...
- spring boot自动配置
首先,一般的java Web项目需要很多配置,web配置(web.xml).spring配置(默认叫applicationContext.xml),非常繁琐 而spring-boot-starter是 ...
- Spring Boot自动配置原理
要了解Spring Boot的自动配置首先我需要先了解Spring Boot的两个机制,一个是配置文件如何进入到系统变成属性,二是如何将这些属性加入到容器中. 首先我们需要有一个组件,这个组件中的属性 ...
- Spring Boot - 自动配置实例解读
文章目录 Pre 启用 debug=true输出自动配置 HttpEncodingAutoConfiguration 什么情况下,Spring Boot 会自动装配 HttpEncodingAutoC ...
- Spring Boot自动配置原理、实战
Spring Boot自动配置原理 Spring Boot的自动配置注解是@EnableAutoConfiguration, 从上面的@Import的类可以找到下面自动加载自动配置的映射. org.s ...
- Spring boot的配置类
@Configuration 指明当前类是一个配置类 来替代之前的Spring配置文件 Spring boot的配置类 相当于Spring的配置文件 容器添加组件 Spring,通过配置文件添加组件 ...
- Spring Boot自动配置原理分析
一.写在前面 随着时间的迁移Spring Boot 越来越多的出现在Java 后端程序员的视野中,Spring Boot 之所以会那么流行,很大的一个原因是自身集成了很多的Bean,简化了传统Srin ...
- 在Spring Boot中配置web app
文章目录 添加依赖 配置端口 配置Context Path 配置错误页面 在程序中停止Spring Boot 配置日志级别 注册Servlet 切换嵌套服务器 在Spring Boot中配置web a ...
最新文章
- ReentrantReadWriteLock读写锁的使用
- 在MVC控制器里面使用dynamic和ExpandoObject,实现数据转义的输出
- Android开发之移动互联网周刊第二期,不错,推荐给大家
- switch( )的经典引用
- randperm--生成随机整数排列
- jmeter 自定义参数_jmeter参数化并在jenkins上执行
- stl clocklist 查找元素_剑指信奥 C++ 之 STL 迭代器(上)
- 《娱乐至死》读书笔记(part4)--只有给观众他们想要的东西,你才可以得到市场占有率
- SAP智能机器人流程自动化解决方案
- 代码证年检所需资料_上海注销小规模公司所需材料及流程
- NSLog 输出格式集合
- sql 查询关联字段 最好取别名 不然会被第一个覆盖
- java getSource()和 getActionCommand()区别
- A Mutex must not be copied after first use. 是什么(nocopy)
- 云服务器选股,【图】老师们能不能在通达信7.48中整合云行情服务器?_选股公式,股票,炒股公式,股票指标,股票论坛_股票软件技术交流论坛_理想论坛 - 股票论坛...
- 3月12日 植树节 Arbor Day / Planting Trees Day
- 阿里面试——机器学习/算法面试经验案例集合
- Python安装与卸载流程
- 仿网易考拉完整源码+答辩ppt(java+mysql+JavaScript)资源详细说明
- 神经系统结构基础是什么,神经系统结构图简笔画
热门文章
- bae index.php,【微信公众平台开发】之一:入门与BAE3.0下操作
- v2视频服务器退出系统怎么启动,V2视频会议系统入门操作手册.doc
- PHP命令行代码更新不及时,PHP脚本从命令行工作,而不是从cron
- 【Java】 leetCode 删除链表中等于给定值 val 的所有节点。
- PTA基础编程题目集-7-15 计算圆周率
- 1013 Battle Over Cities (25分)(用割点做)
- 解题报告(二)E、(BZOJ3513) [MUTC2013] idiots(生成函数 + FFT + 组合计数)
- 【网络流】解题报告:luogu P2740 [USACO4.2]草地排水Drainage Ditches(Edmonds-Karp增广路,最大流模板)
- 时间复杂度,O(1), O(n), O(logn), O(nlogn) 的区别+样例分析
- 免秘登陆linux_linux普通用户免秘钥登陆操作