专栏首页九州牧云Spring Cloud自动推送配置到Consul配置中心

Spring Cloud自动推送配置到Consul配置中心

Consul是一个集配置管理、服务注册和发现于一体的微服务基础组件,它提供的这些功能我们在微服务开发中都用到了。在实践中,我们发现Spring Cloud没有提供在启动时自动加载某一个配置文件到Consul配置中心的功能,于是参照Consul社区的一个开源项目cfg4j-pusher进行了二次开发,实现了Spring Boot应用启动时自动加载指定配置文件到Consul配置中心的功能。以下是软件环境:

  • JDK 1.8
  • Maven 3.3.9
  • Spring Boot 2.0.0.RELEASE
  • Spring Cloud Finchley.M8
  • Consul 1.2.2

实现过程

在这里我新建一个工程来说明实现过程,整个工程的结构如下:

整个工程依照Spring Boot工程的目录结构创建,在com.consul.pusher包下有四个类,其中ConsulApplication的作用就不用说了,它是整个服务的启动类。剩下的三个类说明如下:

  • ConsulConfig:提供加载配置到Consul中的操作。它定义了一个私有的init方法,这个方法被@PostConstruct注解所标记,主要作用是在ConsulConfig依赖注入完成之后读取指定配置文件,将文件里的配置信息推送到Consul配置中心中。该方法在整个应用生命周期中只执行一次,定义为私有的主要是不允许外部调用,保证安全性
  • ConsulServiceConsulServiceImplConsulServiceImpl实现了ConsulService接口,主要提供Consul配置中心业务逻辑操作,它主要封装了consul java client的一些方法。

resources目录下的bootstrap.ymlapplication.yml分别为微服务全局配置文件和业务信息配置文件。在服务启动期间,application.yml配置文件的内容会被ConsulConfig类的init方法读取并推送到Consul配置中心。在这里我们没有将bootstrap.yml的文件内容推送到Consul配置中心,主要是考虑到:

  • bootstrap.yml里定义的配置信息不经常修改
  • Spring Boot天生不支持动态修改数据库、ES连接信息。bootstrap.yml里的定义的数据库连接、ES连接等信息通过Consul配置中心修改后不能生效,还需要重启应用才能生效。并且,需要修改数据库连接、ES连接信息的场景大部分是因为当前服务不可用产生的,服务的高可用不应由Consul来维护

重构升级

经过与团队成员讨论,开发配置自动推送功能的初衷有两个:

  • 方便devops团队进行自动化运维。微服务部署过程中,配置的管理和修改是一件让人头疼的事情,无论是开发和运维,都希望减少手动修改配置的次数,通过自动推送配置功能,可以轻松解决这个问题。Consul官方虽然提供了HTTP API供使用者加载指定配置到Consul中,但是需要开发给运维提供配置文件,再由运维手动执行命令加载这些配置文件到Consul中,不仅容易出错,管理也不便
  • 无论是分布式服务还是微服务,都应该有一套工具化、通用化的公共服务类库。服务开发中,有很多重复的、可以封装成工具类的代码,我们可以构建一个公共服务类库,将这些代码组织起来,供大家使用。这样既解决了代码重复的问题,也使服务更加健壮和高可用。业内优秀的例子比如Apache CommonsGoogle Guava系列类库

基于第二点初衷,产品发布了几版之后,我将自动推送配置的代码抽取了出来,封装成一个公共服务类库。封装之后,工程目录结构如下:

因为公共服务类库不是一个可运行的微服务应用,它以jar包的形式嵌入到微服务应用中,所以需要去除ConsulApplication类,基础库单元测试通过之后,就可以推送到我们的maven私服中。接下来,就是使用这个基础库了,使用步骤如下:

(1) 首先确保服务引入了Consul依赖:

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

(2) 将自定义的配置统一提取到application.yml里。注意:yml文件里如果有空的value值,请用单引号''代替,否则yml解析会报错

(3)pom文件里引入consul-pusher公共服务类库,consul-pusher类库的Consul配置加载类在服务启动时自动加载配置到Consul中:

<dependency>
	<groupId>com.consul.pusher</groupId>
	<artifactId>consul-pusher</artifactId>
	<version>1.0</version>
</dependency>

(4) 在对应服务的Application启动类上,加入@ComponentScan(value = "com.consul.pusher"),使公共类库相关的类被Spring Boot扫描到,比如:

@SpringBootApplication
@EnableDiscoveryClient
@EnableScheduling // 启用定时调度功能,Consul需要使用此功能来监控配置改变
@ComponentScan(value="com.consul.pusher")
public class ExampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(ExampleApplication.class);
    }
}

(5) 加载配置:

使用@Value注入配置,在类上添加@RefreshScope实现业务参数的热更新:

@RefreshScope
@Service
public class StockMarketServiceImpl implements StockMarketService {
 
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	 
	@Value(value = "${kline.host}")
	private String kLineHost;
 
}

至此,整个工程的重构和使用完成。引入consul-pusher的服务启动后,在Consul配置中心创建的配置信息截图如下,以consul-pusher服务本身为例:

源码下载&参考资料

源码链接:

GitHub:consul-pusher

码云:consul-pusher

Consul整合参考链接:

Spring Cloud(二)Consul 服务治理实现

快递中心的spring cloud实践

consul配置中心使用指南

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 在HashMap中将可变对象用作Key,需要注意什么?

    本文中我们将会讨论在Java HashMap中将可变对象用作Key。所有的Java程序员可能都在自己的编程经历中多次用过HashMap。那什么是HashMap呢...

    九州暮云
  • IntelliJ IDEA内存优化最佳实践

    【编者按】本文作者在和同事的一次讨论中发现,对 IntelliJ IDEA 内存采用不同的设置方案,会对 IDE 的速度和响应能力产生不同的影响。

    九州暮云
  • MySQL分库分表方案

    当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。

    九州暮云
  • Consul 1.6 GA 发布

    Consul 1.6.0 已于近日 发布 GA 版本 ,Consul 是 HashiCorp 公司推出的开源工具,也是主流的用于实现分布式系统服务发现与配置的方...

    Debian社区
  • Consul 简介

    1、服务发现:一个客户端提供自己的服务,例如api服务,或者mysql服务,另一个客户端就可以利用Consul通过DNS或者http来发现这些服务的提供者。

    WindWant
  • 斯坦福CS229机器学习笔记-Lecture3 局部加权线性回归和 logistic regression

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.n...

    TeeyoHuang
  • 基于蚁群算法的机械臂打孔路径规划

      该问题来源于参加某知名外企的校招面试。根据面试官描述,一块木板有数百个小孔(坐标已知),现在需要通过机械臂在木板上钻孔,要求对打孔路径进行规划,力求使打孔总...

    waylon
  • 免费好用的Diff和Merge工具大总结

    总结:比较下来:diffmerge和P4merge最好用,kdiff比较专业些,支持自动merge。

    2Simple
  • [PHP] PHP多进程处理tcp连接

    陶士涵
  • 如何通过 Github Action 获取静态资源部署服务

    印记中文一直致力于为国内前端开发者提供技术文档的翻译服务,比如 React, Webpack, Node.js 等技术文档,都能有看到印记中文参与的影子。为了让...

    腾讯云开发TCB

扫码关注云+社区

领取腾讯云代金券