Consul
是一个集配置管理、服务注册和发现于一体的微服务基础组件,它提供的这些功能咱们在微服务开发中都用到了。在实践中,咱们发现Spring Cloud
没有提供在启动时自动加载某一个配置文件到Consul
配置中心的功能,因而参照Consul
社区的一个开源项目cfg4j-pusher进行了二次开发,实现了Spring Boot
应用启动时自动加载指定配置文件到Consul
配置中心的功能。如下是软件环境:html
在这里我新建一个工程来讲明实现过程,整个工程的结构以下:java
整个工程依照Spring Boot
工程的目录结构建立,在com.consul.pusher
包下有四个类,其中ConsulApplication
的做用就不用说了,它是整个服务的启动类。剩下的三个类说明以下:git
ConsulConfig
:提供加载配置到Consul
中的操做。它定义了一个私有的init
方法,这个方法被@PostConstruct
注解所标记,主要做用是在ConsulConfig
依赖注入完成以后读取指定配置文件,将文件里的配置信息推送到Consul
配置中心中。该方法在整个应用生命周期中只执行一次,定义为私有的主要是不容许外部调用,保证安全性github
ConsulService
和ConsulServiceImpl
:ConsulServiceImpl
实现了ConsulService
接口,主要提供Consul
配置中心业务逻辑操做,它主要封装了consul java client的一些方法。spring
resources
目录下的bootstrap.yml
和application.yml
分别为微服务全局配置文件和业务信息配置文件。在服务启动期间,application.yml
配置文件的内容会被ConsulConfig
类的init
方法读取并推送到Consul
配置中心。在这里咱们没有将bootstrap.yml
的文件内容推送到Consul
配置中心,主要是考虑到:数据库
bootstrap.yml
里定义的配置信息不常常修改apache
Spring Boot
天生不支持动态修改数据库、ES
链接信息。bootstrap.yml
里的定义的数据库链接、ES
链接等信息经过Consul
配置中心修改后不能生效,还须要重启应用才能生效。而且,须要修改数据库链接、ES
链接信息的场景大部分是由于当前服务不可用产生的,服务的高可用不该由Consul
来维护bootstrap
通过与团队成员讨论,开发配置自动推送功能的初衷有两个:api
方便devops
团队进行自动化运维。微服务部署过程当中,配置的管理和修改是一件让人头疼的事情,不管是开发和运维,都但愿减小手动修改配置的次数,经过自动推送配置功能,能够轻松解决这个问题。Consul
官方虽然提供了HTTP API供使用者加载指定配置到Consul
中,可是须要开发给运维提供配置文件,再由运维手动执行命令加载这些配置文件到Consul
中,不只容易出错,管理也不便安全
不管是分布式服务仍是微服务,都应该有一套工具化、通用化的公共服务类库。服务开发中,有不少重复的、能够封装成工具类的代码,咱们能够构建一个公共服务类库,将这些代码组织起来,供你们使用。这样既解决了代码重复的问题,也使服务更加健壮和高可用。业内优秀的例子好比Apache Commons、Google 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
整合参考连接: