SpringBoot(19)---SpringBoot整合Apollo
SpringBoot(19)---SpringBoot整合Apollo
有关Apollo之前已经写了两篇文章:
这篇文章分为两部分:
1、跟着官网步骤,快速搭建apollo环境。
2、SpringBoot整合apollo,实现配置中心。
一、Apollo快速搭建
apollo环境的搭建主要参考 官方文档 ,我们就直接一步一步跟着官方文档来
1、下载Quick Start安装包
2、创建数据库
之前有说过,apollo会有两个数据库: ApolloPortalDB
和 ApolloConfigDB
3、更新数据库连接信息
在下载下来的Quick Start项目中,有个叫demo.sh
的文件,我们需要 修改数据库连接信息,修改里头数据库连接地址/用户名/密码
4、 启动Apollo配置中心
上面三部就已经将环境搭建好,现在我们开始启动Apollo配置中心,来看具体效果。
注意
这里默认暂用三个端口: 8070
,8080
,8090
,所以要先看下这三个端口有木有被暂用。
启动项目
./demo.sh start
5、登录Apollo
登录界面
初始账号密码
: apollo/admin
进入首页之后,我们可以看到: 默认的环境只有dev,m默认有一个SampleApp项目
我们在这里添加两个配置
6. 测试客户代码
上面已经设置了两个配置,这个时候我们就需要通过客户端去获取,我们先不通过SpringBoot去获取,而是官方提供的客户端去获取配置
运行客户端
./demo.sh client
启动后去查询配置
可以看到客户端都能够拿到配置中心的配置。
注意
这里有一点在上面我设了 gougou:4岁。而实际客户端获得的是4?,所以中文没有转义成功,在实际开发中,我们也尽量去避免有中文汉字来当配置。
这样下来,官方给的快速启动apollo是成功了,下面我们把客户端换成SpringBoot,来实现获取配置中心的数据。
二、SpringBoot整合Apollo
从上面我们可以知道在apollo官方给了我们一个默认项目叫:SampleApp。默认的用户名称:apollo。所以这里灵活一点,不用它自己的,而是我们手动新增。
1、Apollo创建新新用户和项目
1)新增新用户
http://{portal地址}/user-manage.html //我们这里设置的是http://localhost:8070/user-manage.html
这里新增一个用户名叫:liubei
2)新增项目
访问http://localhost:8070 登录后,选择创建项目。
这里新创建了项目,一个AppId名称叫: springboot-test-apollo
。
配置说明
:
部门:选择应用所在的部门。(想自定义部门,参照官方文档,这里就选择样例)
应用AppId:用来标识应用身份的唯一id,格式为string,需要和客户端。application.properties中配置的app.id对应。
应用名称:应用名,仅用于界面展示。
应用负责人:选择的人默认会成为该项目的管理员,具备项目权限管理、集群创建、Namespace创建等权限。
提交配置后会出现如下项目配置的管理页面。
3)添加配置
这里先添加一个新配置: date.value = 2020.08.04 。
2、springboot项目搭建
上面把apollo环境搭建好,也创建了新项目,那么这里就去读取新项目的配置信息。
1)pom.xml
添加 Apollo 客户端的依赖,其它依赖这里就不展示了,完整项目会放在github上。
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.3.0</version>
</dependency>
2)application.yml
server:
port: 8123
app:
id: springboot-test-apollo
apollo:
meta: http://127.0.0.1:8080
bootstrap:
enabled: true
eagerLoad:
enabled: true
#这里说明在将该项目 com目录下的日志,都采用info模式输出
logging:
level:
com: info
配置说明
app.id :AppId是应用的身份信息,是配置中心获取配置的一个重要信息。
apollo.bootstrap.enabled:在应用启动阶段,向Spring容器注入被托管的application.properties文件的配置信息。
apollo.bootstrap.eagerLoad.enabled:将Apollo配置加载提到初始化日志系统之前。
logging.level.com :调整 com 包的 log 级别,为了后面演示在配置中心动态配置日志级别。
3) TestController
@Slf4j
@RestController
public class TestController {
@Value( "${date.value}" )
String dateValue;
@GetMapping("test")
public String test() {
return "打印配置中心的 dateValue 值: "+ dateValue;
}
}
4)SpringBoot启动类
@SpringBootApplication
@EnableApolloConfig
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
添加 EnableApolloConfig 配置注解
3、测试
我在apollo配置了一个属性: date.value = 2020.08.04,如果从springBoot能够获取到该配置,那么就说明成功了。
很明显,我们通过接口已经成功获取配置中心的配置。这样一个最简单的整合已经完成了,下面我们在来验证其它东西。
三、验证
下面我们来验证一些有意思的东西:
1)、配置修改后能否立即生效。
2)、通过配置日志打印级别,我们来验证能够动态的修改日志级别
3)、能够通过修改端口号,能够修改项目运行的端口号。
下面我们一个一个来验证
1、配置修改后能否立即生效?
新增一个接口
@Slf4j
@RestController
public class TestController {
@Value( "${date.value}" )
String dateValue;
@GetMapping("test1")
public void test1() {
log.info("当前配置中心的 dateValue 值 = {}",dateValue);
}
}
步骤
:1)先请求接口一次。2)然后修改apollo配置中心。3)然后在请求一次该接口。
结论
从图中很明显看出第一次和第二次请求的接口,返回的配置信息已经不一样了。说明配置是会时时更新的。而且当我在apollo界面修改配置的时候,
控制台日志也会输出相关信息。
2、动态修改日志级别
我们来思考有没有这么一种需求,我们在线上的日志级别一般是INFO级别的,主要记录业务操作或者错误的日志。那么这个时候当线上环境出现问题希望输出DEBUG
日志信息辅助排查的时候怎么办呢?
如果以前,我们可以会修改配置文件,重新打包然后上传重启线上环境,以前确实是这么做的。通过Apollo配置中心我们可以实现不用重启项目,就可以实现让日志
基本从INFO变成DEBUG。下面我们来演示一番。
在项目启动之前,我在application.yml
配置了日志级别是info模式。我们来请求下面接口验证下。
@GetMapping("test2")
public void test2() {
log.debug("我是 debug 打印出的日志");
log.info("我是 info 打印出的日志");
log.error("我是 error 打印出的日志");
}
请求下接口看下控制台
可以很明显的看出,控制台只打印info级别以上的日志,并没有打印debug日志。
现在我们要做的是将打印日志级别不在交给application.yml
而是交给apollo
来配置。这里其实要做两步:
1)、在apollo配置一条日志数据。
2)、通过监听配置的变化,来达到热更新的效果。
java配置类
@Configuration
public class LoggerConfig {
private static final Logger logger = LoggerFactory.getLogger(LoggerConfig.class);
private static final String LOGGER_TAG = "logging.level.";
@Autowired
private LoggingSystem loggingSystem;
@ApolloConfig
private Config config;
@ApolloConfigChangeListener
private void configChangeListter(ConfigChangeEvent changeEvent) {
refreshLoggingLevels();
}
@PostConstruct
private void refreshLoggingLevels() {
Set<String> keyNames = config.getPropertyNames();
for (String key : keyNames) {
if (StringUtils.containsIgnoreCase(key, LOGGER_TAG)) {
String strLevel = config.getProperty(key, "info");
LogLevel level = LogLevel.valueOf(strLevel.toUpperCase());
loggingSystem.setLogLevel(key.replace(LOGGER_TAG, ""), level);
logger.info("{}:{}", key, strLevel);
}
}
}
}
关键点讲解
@ApolloConfig注解:将Apollo服务端的中的配置注入这个类中。
@ApolloConfigChangeListener注解:监听配置中心配置的更新事件,若该事件发生,则调用refreshLoggingLevels方法,处理该事件。
ConfigChangeEvent参数:可以获取被修改配置项的key集合,以及被修改配置项的新值、旧值和修改类型等信息。
从上面可以看出,通过@PostConstruct
项目启动的时候就去获取apollo的日志级别去覆盖application.yml
日志级别。我在apollo配置中心,新增加一条日志配置。
把日志级别设置error,那么在项目启动的时候,因为PostConstruct注解的原因,所以会去执行一次refreshLoggingLevels方法,把当前日志级别改成error。
apollo配置
我们重启启动项目再来看下,请求上面接口结果。
从上图我们就可以看出,我们同时在application.yml
和apollo
都配置了日志打印级别,但实际上打印出来的结果来看,最终是以apollo为准。
现在我们再来尝试下,我们修改apollo配置,把日志级别修改成debug级别。
apollo配置
因为我们在LoggerConfig中,有个 @ApolloConfigChangeListener
注解,我们在修改配置的时候都会被监听到,监听到之后就会把当前的日志级别,换成最新的。
我们再来请求接口,看下控制台。
总结
通过上面的验证,可以得出:我在没有重启服务器的情况下,实现了日志级别动态切换的功能。
3、动态修改端口号
这里我就不把验证的过程发出来了,结论就是不可以。如果要验证,在上面的refreshLoggingLevels方法中,加入修改端口的逻辑。
其实理由很简单,因为端口跟进程绑定在一起的,你的进程起来了,端口就无法改变。如果一定要换端口号,那么就需要有一个独立进程,去杀掉你的项目进程,
再起一个新的不同端口的进程。显然apollo没有这样的功能,而且个人觉得也没啥意义。。
好了,整篇文章到这里就结束了,下面把该项目的具体代码放到github上。
GitHub地址
:SpringBoot整合Apollo
参考
1、官方文档
别人骂我胖,我会生气,因为我心里承认了我胖。别人说我矮,我就会觉得好笑,因为我心里知道我不可能矮。这就是我们为什么会对别人的攻击生气。
攻我盾者,乃我内心之矛(29)
SpringBoot(19)---SpringBoot整合Apollo的更多相关文章
- SpringBoot与Dubbo整合下篇
(1)pom.xml引入相关依赖jar包,如下: <dependency> <groupId>com.alibaba</groupId> <artifactI ...
- SpringBoot+Shiro+mybatis整合实战
SpringBoot+Shiro+mybatis整合 1. 使用Springboot版本2.0.4 与shiro的版本 引入springboot和shiro依赖 <?xml version=&q ...
- 【springboot spring mybatis】看我怎么将springboot与spring整合mybatis与druid数据源
目录 概述 1.mybatis 2.druid 壹:spring整合 2.jdbc.properties 3.mybatis-config.xml 二:java代码 1.mapper 2.servic ...
- SpringBoot学习之整合Mybatis
本博客使用IDEA开发工具,通过Maven构建SpringBoot项目,初始化项目添加的依赖有:spring-boot-starter-jdbc.spring-boot-starter-web.mys ...
- SpringBoot与Mybatis整合方式01(源码分析)
前言:入职新公司,SpringBoot和Mybatis都被封装了一次,光用而不知道原理实在受不了,于是开始恶补源码,由于刚开始比较浅,存属娱乐,大神勿喷. 就如网上的流传的SpringBoot与Myb ...
- Springboot security cas整合方案-实践篇
承接前文Springboot security cas整合方案-原理篇,请在理解原理的情况下再查看实践篇 maven环境 <dependency> <groupId>org.s ...
- Springboot security cas整合方案-原理篇
前言:网络中关于Spring security整合cas的方案有很多例,对于Springboot security整合cas方案则比较少,且有些仿制下来运行也有些错误,所以博主在此篇详细的分析cas原 ...
- 使用Springboot + Gradle快速整合Mybatis-Plus
使用Springboot + Gradle快速整合Mybatis-Plus 作者:Stanley 罗昊 [转载请注明出处和署名,谢谢!] MyBatis-Plus(简称 MP)是一个 MyBatis ...
- springboot 与 shiro 整合 (简洁版)
前言: 网上有很多springboot 与 shiro 整合的资料,有些确实写得很好, 对学习shiro和springboot 都有很大的帮助. 有些朋友比较省事, 直接转发或者复制粘贴.但是没有经过 ...
随机推荐
- mongoose子文档生成不了_id,查询困难的解决办法
以下是我的数据库表 本来是想设置一个自增属性,比如listId,来定义我的子list,sliderlist这些,这样能确保他的唯一性,结果尝试了很久都无法成功,原生,插件都无法成功, 这两个网址是讲的 ...
- float对内联元素和块元素的影响
写在前面:附一篇w3s的关于css float的讲解:http://www.w3school.com.cn/css/css_positioning_floating.asp float属性还没有彻底了 ...
- Python 数字数据类型
数字数据类型,包括整数.浮点数.复数和布尔类型. 整数 int 长整型(数字长度不限制):包括正数,负数,0. # 正数 num_int = 123 print(type(num_int)) # &l ...
- matplotlib绘制子图
fig,subs = plt.subplots(2,2) subs[0][0].plot(data_math_C1) subs[0][0].set_title('C_1 曲线') subs[0][1] ...
- PHP imagechar - 写出横向字符
imagechar — 写出横向的字符.高佣联盟 www.cgewang.com 语法 bool imagechar ( resource $image , int $font , int $x , ...
- PHP str_split() 函数
实例 把字符串 "Hello" 分割到数组中: <?php print_r(str_split("Hello")); ?>高佣联盟 www.cgew ...
- LeetCode 87,远看是字符串其实是搜索,你能做出来吗?
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第54篇文章,我们一起来看LeetCode 87题,Scramble String(爬行字符串). 这题的官方难度 ...
- AutoMapper 9.0的改造
AutoMapper于2019.8.12升级9.0 从此不再支持静态的对象转换 自己琢磨了一下,写了一套扩展 官方链接如下 https://github.com/AutoMapper/AutoMapp ...
- linxu系统安装WordPress
确保在安装wordpress之前,安装了nginx,php,mysql 没有安装的翻我之前的博文有安装方法 进入官网下载压缩包 wget https://wordpress.org/latest.ta ...
- klassVtable与klassItable
klassVtable与klassItable类用来实现Java方法的多态,也可以叫动态绑定,是指在应用执行期间通过判断接受对象的实际类型,根据实际类型调用对应的方法.C++为了实现多态,在对象中嵌入 ...