Consul 是 HashiCorp 公司推出来的开源产品。主要提供了:服务发现、服务隔离、服务配置等功能。相比于 其他注册中心组件Eureka 和Zookeeper,Consul 配置更加一站式,因为它内置了很多微服务常见的功能:服务发现与注册、分布式一致性协议实现、健康检查、键值对存储、多数据中心等,我们不再需要借助第三方组件来实现这些功能。
Spring Cloud Consul 具有如下特性:
不同于 Eureka ,Consul 使用 Go 语言开发,所以我们需要先安装Consul 。
从官网直接下载软件,官网下载地址:https://www.consul.io/downloads.html。下载完成后只有一个exe文件,双击运行;
在命令行中输入以下命令可以查看版本号:
consul --version
使用开发模式启动:
consul agent -dev

浏览器访问 http://localhost:8500 ,进入Consul首页。

在 Linux 中,首先执行如下命令下载 Consul:
wget https://releases.hashicorp.com/consul/1.6.2/consul_1.6.2_linux_amd64.zip
下载完成后解压压缩包
unzip consul_1.6.2_linux_amd64.zip

解压完成后,我们可以看到consul文件,然后执行以下命令启动consul:
./consul agent -dev -ui -node=consul-dev -client=192.168.91.128
注意:192.168.91.128应该为内网ip。还要确保8500端口可用
启动成功后,浏览器请求http://101.43.30.7:8500/ui/dc1/services,访问consul管理后台

创建Spring Boot项目,作为服务提供者,添加以下依赖:

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
成功创建项目后,application.properties添加如下配置:
spring.application.name=consul-provider
server.port=2000
#consul的主机地址
spring.cloud.consul.host=101.43.30.7
#conusl的端口
spring.cloud.consul.port=8500
#服务的名称
spring.cloud.consul.discovery.service-name=consul-provider
spring.cloud.consul.discovery.heartbeat.enabled=true
在启动类上开启服务发现的功能:
@SpringBootApplication
//开启服务发现功能
@EnableDiscoveryClient
public class ConsulProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ConsulProviderApplication.class, args);
}
}
启动项目,访问consul管理后台界面,可以看到已经注册成功。

创建HelloController添加接口/hello
@RestController
public class HelloController {
@Value("${server.port}")
Integer port;
@GetMapping("/hello")
public String hello(){
return "hello" + port;
}
}
对项目进行打包,命令行启动多一个provider实例:
java -jar consul-provider-0.0.1-SNAPSHOT.jar --server.port=6000
consul管理后台可以看到有两个provider实例

创建Spring Boot项目consul-consumer,作为服务消费者,添加以下依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
成功创建项目后,application.properties添加如下配置:
spring.application.name=consul-consumer
server.port=2002
#consul的主机地址
spring.cloud.consul.host=101.43.30.7
#conusl的端口
spring.cloud.consul.port=8500
#服务的名称
spring.cloud.consul.discovery.service-name=consul-consumer
在启动类上开启服务发现的功能,并注入RestTemplate:
@SpringBootApplication
@EnableDiscoveryClient
public class ConsulConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsulConsumerApplication.class, args);
}
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}
测试服务调用
@RestController
public class HelloController {
@Autowired
LoadBalancerClient loadBalancerClient;
@Autowired
RestTemplate restTemplate;
@GetMapping("/hello")
public void hello() {
ServiceInstance choose = loadBalancerClient.choose("consul-provider");
System.out.println("服务地址:" + choose.getUri());
System.out.println("服务名称:" + choose.getServiceId());
String s = restTemplate.getForObject(choose.getUri() + "/hello",
String.class);
System.out.println(s);
}
}
这里通过loadBalancerClient获取要调用的ServiceInstance,获取到调用地址之后再使用RestTemplate去调用。浏览器请求http://localhost:2002/hello ,查看控制台的请求结果。

创建Maven模块consul-config,在pom.xml中添加如下依赖:
<?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>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>top.javahai</groupId>
<artifactId>consul-config</artifactId>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR6</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
添加配置文件application.yml,配置启用dev环境:
spring:
profiles:
active: dev
添加配置文件bootstrap.yml,对Consul的配置功能进行配置:
server:
port: 9101
spring:
application:
name: consul-config
cloud:
consul:
host: localhost
port: 8500
discovery:
serviceName: consul-config
#打开心跳机制
heartbeat:
enabled: true
config:
#是否启用配置中心功能
enabled: true
#设置配置值的格式
format: yaml
#设置配置所在目录
prefix: config
#设置配置的分隔符
profile-separator: ':'
#配置key的名字,由于Consul是K/V存储,配置存储在对应K的V中
data-key: data
创建ConfigController,提供接口/configInfo,从Consul配置中心中获取配置信息.使用@RefreshScope注解动态加载配置文件。
@RestController
@RefreshScope
public class ConfigController {
@Value("${config.info:}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo() {
return configInfo;
}
}
在Consul后台添加如下配置:
添加配置存储的key为:
config/consul-config:dev/data
添加配置存储的value为:
config:
info:"config info onsul-config for dev"

启动项目调用/configinfo接口查看配置信息。
我们修改Consul中的配置信息,再次调用查看配置的接口,就会发现配置也刷新了。这是因为Consul使用其自带的Control Bus 实现了一种事件传递机制,从而实现了动态配置刷新功能。