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)