Spring Cloud Consul配置中心 之前学习过了Spring Cloud Config
,它提供了配置中心的功能,但是需要配合git
、svn
或外部存储(例如各种数据库),而且需要配合Spring Cloud Bus
实现配置刷新。
Spring Cloud Consul
,之前学习了它作为注册中心的使用方案,且作为 Spring Cloud
官方推荐替换 Eureka
注册中心的方案。既然使用了 Consul
,就可以使用 Consul
提供的配置中心功能,并且不需要额外的 git
、svn
、数据库等配合,且无需配合 Bus
即可实现配置刷新。
Spring Cloud Consul
1. Consul 介绍 Console 是 HashiCorp
公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其它分布式服务注册与发现的方案,Consul
的方案更一站式 ,内置了服务注册与发现框架、分布式一致性协议实现、健康检查、Key/Value 存储(配置中心)
、多数据中心方案,不再需要依赖其它工具(比如 ZooKeeper
等),使用起来也较为简单。
Consul
使用 Go
语言编写,因此具有天然可移植性(支持Linux
、Windows
和 Mac OS
);安装包仅包含一个可执行文件,方便部署,与 Docker
等轻量级容器可无缝配合。
2. Consul 特性
服务发现
健康检查
KV
存储(配置中心)
安全服务通信
多数据中心
3. Consul 安装 下载 Downloads | Consul by HashiCorp
安装
Windows下单节点安装
下载后的压缩包解压后就只有一个consul.exe
的执行文件。
cd
到对应的目录下,使用 cmd
启动 Consul
。
1 2 # -dev表示开发模式运行 consul agent -dev -client=0.0.0.0
为了方便启动,也可以在 consul.exe
同级目录下创建一个脚本来启动,脚本内容如下:
1 2 consul agent -dev -client=0.0.0.0 pause
访问管理后台:http://localhost:8500/ 看到下图意味着我们的 Consul 服务启动成功了。
4. 初始化配置 创建基本目录 使用 Consul
作为配置中心,第一步我们先创建目录,把配置信息存储至 Consul
。
点击菜单 Key/Value
再点击 Create
按钮。
创建 config/
基本目录,可以理解为配置文件所在的最外层文件夹。
创建应用目录
创建 orderService/
应用目录,存储对应微服务应用的 default
环境配置信息。
多环境应用目录 假设我们的项目有多环境:default
、test
、dev
、prod
,在 config
目录下创建多环境目录。
orderService
文件夹对应 default
环境
orderService-test
文件夹对应 test
环境
orderService-dev
文件夹对应 dev
环境
orderService-prod
文件夹对应 prod
环境
初始化配置 以 dev
环境为例,点击orderService-dev
进入文件夹。
点击Create
按钮准备创建Key/Value
配置信息。
填写Key
:orderServiceConfig
填写Value
:
1 2 3 4 5 6 name: order-service-dev mysql: host: localhost port: 3006 username: root password: root
假设以上内容为订单微服务的配置信息,下面我们通过案例来加载 Consul
配置中心中的配置信息。
5. 环境准备
spring-cloud-demo-consul-config
Maven
聚合工程
订单服务:order-service01
和order-service02
6. 实践案例 添加依赖 需要从 Consul 获取配置信息的项目主要添加 spring-cloud-starter-consul-config
依赖,完整依赖如下:
order-service01
和 order-service02
核心依赖一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <?xml version="1.0" encoding="UTF-8"?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <parent > <artifactId > spring-cloud-demo-consul-config</artifactId > <groupId > com.springcloud.demo</groupId > <version > 0.0.1-SNAPSHOT</version > </parent > <modelVersion > 4.0.0</modelVersion > <artifactId > order-service01</artifactId > <properties > <maven.compiler.source > 8</maven.compiler.source > <maven.compiler.target > 8</maven.compiler.target > </properties > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > <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 > </dependencies > </project >
配置文件 配置文件必须叫 bootstrap.yml
我们除了使用 Consul
配置中心功能之外,把微服务也注册到 Consul
注册中心去。order-service01
和 order-service02
的配置项中除了端口和注册实例 id 之外,其余配置项一致,完整配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 server: port: 9090 spring: application: name: order-service profiles: active: dev cloud: consul: host: localhost port: 8500 config: enabled: true prefix: config default-context: orderService profile-separator: '-' format: YAML data-key: orderServiceConfig watch: enabled: true delay: 1000 discovery: register: true instance-id: ${spring.application.name}-01 service-name: ${spring.application.name} port: ${server.port} prefer-ip-address: true ip-address: ${spring.cloud.client.ip-address}
配置文件实体类 order-service01
和 order-service02
实体类代码一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package com.springcloud.demo.config;import lombok.Data;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;@ConfigurationProperties (prefix = "mysql" )@Component @Data public class MySQLProperties { private String host; private Integer port; private String username; private String password; }
控制层 order-service01
和 order-service02
控制层代码一致。
❗注意:需要添加 @RefreshScope
注解用于重新刷新作用域实现属性值自动刷新。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package com.springcloud.demo.controller;import com.springcloud.demo.config.MySQLProperties;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.cloud.context.config.annotation.RefreshScope;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RefreshScope @RestController public class ConfigController { @Autowired private MySQLProperties mySQLProperties; @Value ("${name}" ) private String name; @GetMapping ("/name" ) public String getName () { return name; } @GetMapping ("/mysql" ) public MySQLProperties getMySQLProperties () { return mySQLProperties; } }
启动类 order-service01
和 order-service02
启动类代码一致。
1 2 3 4 5 6 7 8 9 10 11 package com.springcloud.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class OrderServiceApplication { public static void main (String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }
测试 修改配置信息前 访问:http://localhost:9090/name 结果如下:
访问:http://localhost:9090/mysql 结果如下:
修改配置信息 修改 Consul 配置中心 orderService-dev
环境的配置信息为:
1 2 3 4 5 6 name: order-service-dev-v2.2 mysql: host: localhost port: 3006 username: root123456 password: root123456
修改配置信息后 控制台打印信息如下:
1 2 3 4 5 2022-06-28 23:00:21.431 INFO 52920 --- [TaskScheduler-1] o.s.cloud.commons.util.InetUtils : Cannot determine local hostname 2022-06-28 23:00:22.586 INFO 52920 --- [TaskScheduler-1] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-config/order-service-dev/'}, BootstrapPropertySource {name='bootstrapProperties-config/order-service/'}, BootstrapPropertySource {name='bootstrapProperties-config/orderService-dev/'}, BootstrapPropertySource {name='bootstrapProperties-config/orderService/'}] 2022-06-28 23:00:22.587 INFO 52920 --- [TaskScheduler-1] o.s.boot.SpringApplication : The following profiles are active: dev 2022-06-28 23:00:22.592 INFO 52920 --- [TaskScheduler-1] o.s.boot.SpringApplication : Started application in 2.457 seconds (JVM running for 593.8) 2022-06-28 23:00:22.647 INFO 52920 --- [TaskScheduler-1] o.s.c.e.event.RefreshEventListener : Refresh keys changed: [spring.cloud.client.hostname, name, mysql.password, mysql.username]
Consul 使用 Spring 定时任务 Spring TaskScheduler
来监听配置文件的更新。
默认情况下,它是一个定时任务线程池 ThreadPoolTaskScheduler
,其poolSize
值为 1
。要更改TaskScheduler
,请创建一个TaskScheduler
使用 ConsulConfigAutoConfiguration.CONFIG_WATCH_TASK_SCHEDULER_NAME
常量命名的 bean 类型。
Spring Cloud Consul
访问:http://localhost:9090/name 结果如下:
访问:http://localhost:9090/mysql 结果如下:
7. 总结 HashiCorp
公司的 Consul
可谓是一款全能组件。可用于提供服务发现和服务配置的工具。用 go
语言开发,具有很好的可移植性,被 Spring Cloud
纳入其中。
在注册中心 方面,Netflix Eureka
停止新版本开发,Consul
成为了优秀的可替代方案。
在配置中心 方面,Consul
亦可替代 Spring Cloud Config
作为配置中心使用,且无需配合 Git
、SVN
等工具,无需配合 Bus
消息总线即可实现集群配置更新。
参考资料:
Spring Cloud 系列之 Consul 配置中心 - 哈喽沃德先生 (mrhelloworld.com)