企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
本节为大家介绍:spring cloud config客户端的配置刷新,其实核心内容与《apollo实例配置热更新》差不多。需求都是在配置发生更改之后,将配置值的结果更新到客户端程序中。因此我们首先要明白两个问题: 1. 哪些配置刷新之后可以更新,哪些配置刷新之后也无效?参考《apollo实例配置热更新》第一小节,一样。 2. spring cloud config可以对哪些注解标注的配置进行刷新。下面两个例子都可以将"user.init.password"键对应的值热更新到password和defaultPwd对象上。 3. 这两个注解需要结合`@RefreshScope`注解使用才能使配置热更新生效。 ~~~ @RefreshScope //这里需要加上RefreshScope注解 @ConfigurationProperties(prefix = "user.init") public class User{ private String password; } ~~~ 下文中会针对这种@Value注解的方法为例进行讲解。 ~~~ @RefreshScope //这里需要加上RefreshScope注解 public class Xxxxx{ @Value("${user.init.password}") private String defaultPwd; } ~~~ ## 一、使微服务客户端具备配置刷新能力 ### 1.1. 业务回顾 我们在《第一个微服务》调用章节,就介绍了aservice-rbac下面的服务:为用户重置密码的接口服务“/sysuser/pwd/reset”,前面的章节我们多次用到。其中红色的部分:从数据库的sys\_config表里面加载param\_key="user.init.password"对应的param\_value(也就是用户的默认密码)。 ![](https://img.kancloud.cn/c2/88/c2880cb8eeae62e49570f3c5822f8548_1250x457.png) 现在我们有了config服务配置中心,这个sys\_config数据库表我们就完全可以放弃了。我们把配置写在git仓库里面,进行集中管理。 ### 1.2.发布一个自定义配置 首先,我们去config的git配置仓库**zimug-server-config-repo/aservice-rbac-dev.yml**增加配置:user.init.password=12345678,并将其发布 ![](https://img.kancloud.cn/50/a8/50a8f9d7ca9e4afeeace621de54ee83f_1016x92.png) ![](https://img.kancloud.cn/64/70/6470e78ec98ae927add4b4d129fd1da9_956x89.png) ### 1.3.为微服务客户端增加配置刷新能力 **为aservice-rbac服务增加actuator**,因为actuator可以为我们提供“/actuator/refresh”配置刷新接口 ~~~ <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ~~~ 配置actuator,在git仓库的**zimug-server-config-repo/aservice-rbac-dev.yml**中增加配置 * management.endpoints.web.exposure.include=refresh,health,表示我们只开放配置刷新接口和健康检查接口 ~~~ management: endpoints: web: exposure: include: refresh,health ~~~ 在需要进行配置刷新的类上使用`@RefreshScope`,user.init.password对应的配置对象defaultPwd的值就**初步具备刷新的能力**。 ~~~ @Service @RefreshScope public class SysuserService { @Value("${user.init.password}") private String defaultPwd; public void pwdreset(Integer userId){ if(userId == null){ throw new CustomException(CustomExceptionType.USER_INPUT_ERROR, "重置密码必须带主键"); }else{ SysUser sysUser = sysUserMapper.selectByPrimaryKey(userId); //String defaultPwd = dbLoadSysConfig.getConfigItem("user.init.password"); sysUser.setPassword(passwordEncoder.encode(defaultPwd)); sysUserMapper.updateByPrimaryKeySelective(sysUser); smsService.send(sysUser.getPhone(),"您好,管理员已经将您的密码重置为" + defaultPwd); } } } ~~~ ## 二、测试:手动触发配置刷新 ### 2.1.测试初始自定义配置是否生效 使用postman向“/sysuser/pwd/reset”接口发送请求 ![](https://img.kancloud.cn/12/11/1211d4a0d637c2a588aa3d67c33d3a10_1091x247.png) 在SysUserService服务层(上面的代码)这一行下一个断点。可以看到密码是123456,说明我们的自定义配置加载生效了。 ![](https://img.kancloud.cn/6a/a9/6aa9a236b41ef936a5a6763e67c7691d_1262x439.png) ### 2.2.手动刷新配置 * 我们去Git仓库,将user.init.password=12345678,修改为user.init.password=Abcd1234 * 通过POST请求发送到`http://localhost:8401/actuator/refresh`,触发aservice-rbac的配置进行刷新,即刷新user.init.password配置。 ![](https://img.kancloud.cn/d4/bb/d4bbe6d73a9fdaad3aa513a0ece79f9f_1288x457.png) 使用postman向“/sysuser/pwd/reset”接口再次发送请求,仍在上文处下断点,这次的值为Abcd1234,证明我们配置刷新成功了。而且我们没有重新启动应用。 ![](https://img.kancloud.cn/fb/f2/fbf2f701086cf0da752d44d6b028cd8b_622x82.png) ## 三、如何实现配置自动刷新 那么有没有一种方法,能够实现配置修改之后,自动去向`http://localhost:8401/actuator/refresh`发送请求,更新配置?是有方法的,但是不好。实际生产中几乎没法用,不好也给大家说说,学习一下。 我们可以在Git仓库中配置一个webhook,所谓webhook的作用就是每当git仓库有接收到push代码请求时,都会去向自定义指定URL发送POST请求。我们完全可以利用webhook进行配置的自动刷新。 ![](https://img.kancloud.cn/f1/1f/f11fc543cb2f18d3b9257b6d99fb916f_1228x744.png) 这是一种方法给大家放在这学习一下,但是笔者重来没这么做过,基于以下几点原因: * 微服务客户端必须提供公网地址才能访问到,实际生产或开发环境谁会把自己的内部服务全部暴露到公网?(上图中的127.0.0.1要换成公网ip才可以,内网ip是无法访问到的) * webhook发送请求是无法区分项目、无法区分环境的。该向哪一个项目的,哪一个环境,哪一个实例发送`/actuator/refresh`请求?不能随便配吧。 * 最重要的原因:程序员提交代码的行为不可控,不能因为配置代码变更了就认为这种变更是正确的,不代表可以自动的应用到环境中。 基于以上原因,都不如自己决定向哪里发送`/actuator/refresh`请求。甚至写一个简单的管理程序,都比使用webhook强。当然如果我们想通过spring cloud config实现微服务配置的全量刷新、批量刷新、局部刷新,还有终极解决方案,那就是结合Spring Cloud Bus使用,后面章节我们会讲到。