Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其他工具(比如 ZooKeeper 等)。使用起来也较 为简单。Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。
Consul在业界最广泛的用途就是作为服务注册中心,同Eureka类型,consul作为服务注册中心它的注册和发现流程:
在上面的流程图上有三个角色,分别为服务注册中心、服务提供者、服务消费者。
1.服务提供者Provider启动的时候,会向Consul发送一个请求,将自己的host、ip、应用名、健康检查等元数据信息发送给Consul
2.Consul 接收到 Provider 的注册后,定期向 Provider 发送健康检查的请求,检验Provider是否健康
3. 服务消费者Consumer会从注册中心Consul中获取服务注册列表,当服务消费者消费服务时,根据应用名从服务注册列表获取到具体服务的实例(1个或者多个),从而完成服务的调用。
点我下载
从页面可以看出来consul支持支持Mac、Linux、Windows等各大操作系统,我这里以Windows环境进行展示,下载完后进行解压,只有一个.exe可以执行文件,接下来在此目录下打开CMD,输入命令即可进行启动
consul agent -dev # -dev表示开发模式运行,另外还有-server表示服务模式运行
也可以在此目录下创建一个run.bat的脚本来进行启动:
consul agent -dev
pause
启动完成后会有日志不停的跳出,此时打开浏览器输入:http://localhost:8500,就可以看到consul的管理界面
看到这个界面就说明consul启动成功了。
接下来我们进行代码的编写
讲解如何使用Spring Cloud Consul来进行服务注册和发现的,并且使用Feign来消费服务。本次演示一共有2个工程:
服务提供者 consul-provider 8100
服务消费者 consul-consumer 8200
服务提供者consul-provider
创建一个工程consul-provider,在工程的pom文件引入以下依赖
org.springframework.cloud
spring-cloud-starter-consul-discovery
org.springframework.boot
spring-boot-starter-web
在工程的配置文件application.yml做下以下配置:
server:
port: 8100
spring:
application:
name: consul-provider
cloud:
consul:
host: localhost
port: 8500
discovery:
serviceName: ${spring.application.name}
在项目的启动类加上@EnableDiscoveryClient注解,开启服务发现的功能。
@SpringBootApplication
@EnableDiscoveryClient
public class ConsulProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ConsulProviderApplication.class, args);
}
}
写一个对外开放的接口,代码如下。
@RestController
public class HiController {
@Value(" ${spring.application.name}")
String serviceName;
@GetMapping("/hi")
public String hi(@RequestParam String name) {
return "hi"+name+",i am from :" +serviceName;
}
}
启动工程,在浏览器上访问http://localhost:8500,页面显示如下:
可以看到,consul-provider服务已经成功注册到consul上面去了。
服务消费者consul-consumer
服务消费者的搭建过程同服务提供者,在pom文件中引入的依赖,在配置文件application.yml配置,不同的点在端口为8200,服务名为consul-consumer。
写一个FeignClient,该FeignClient调用consul-provider的接口,代码如下:
@FeignClient(value = "consul-provider")
public interface ConsulClientFeign {
@GetMapping(value = "/hi")
String sayClientConusl(@RequestParam(value = "name") String name);
}
Service层代码如下:
@Service
public class providerService {
@Autowired
private ConsulClientFeign consulClientFeign;
public String say(String name){
return consulClientFeign.sayClientConsul(name);
}
}
写一个对外开放的接口,该接口调用了consul-provider的服务,代码如下:
@RestController
public class HiController {
@Autowired
private ProviderService providerService ;
@GetMapping("/hi")
public String hi(@RequestParam( defaultValue = "jack",required = false)String name){
return providerService .say(name);
}
}
在浏览器上访问http://localhost:8200/hi,浏览器响应如下:
hi jack,i am from consul-provider
这说明consul-consumer已经成功调用了consul-provider的服务。
使用Spring Cloud Consul Config来做服务配置中心
Consul不仅可以用来服务注册和发现,而且支持Key/Value键值对的存储,可以用来做配置中心。
本案例在上一个案例的consul-provider基础上进行改造。首先在pom文件加上consul-config的依赖
org.springframework.cloud
spring-cloud-starter-consul-config
然后在配置文件application.yml加上以下的以下的配置,配置如下:
spring:
profiles:
active: dev
配置指定了SpringBoot启动时的读取的profiles为dev。
然后在工程的启动配置文件bootstrap.yml文件中配置以下的配置:
spring:
application:
name: consul-provider
cloud:
consul:
host: localhost
port: 8500
discovery:
serviceName: ${spring.application.name}
config:
enabled: true
format: yaml
prefix: config
data-key: data
关于spring.cloud.consul.config的配置项描述如下:
enabled 设置config是否启用,默认为true
format 设置配置的值的格式,可以yaml和properties
prefix 设置配的基本目录,比如config
date-key为应用配置的key名字,值为整个应用配置的字符串。
网页上访问consul的KV存储的管理界面,即http://localhost:8500点击上边的key/value一栏,创建一条配置信息,
key值为:config/consul-provider:dev/data
value值如下:
service:
name: consul-provider
server:
port: 8080
在这里插入图片描述
在consul-provider项目编写一个接口,该接口返回从consul 配置中心读取service.name的值,代码如下:
@RestController
public class FooBarController {
@Value("${service.name}")
String name;
@GetMapping("/name")
public String getServiceName() {
return name;
}
}
启动工程,可以看到程序的启动端口为8080。启动完成后,在浏览器上访问http://localhost:8080/name,页面显示consul-provider。由此可见应用consul-provider已经从consul的配置中心读取了配置。
动态刷新配置
使用spring cloud config作为配置中心的时候,可以使用spring cloud config bus支持动态刷新配置。Spring Cloud Consul Config默认就支持动态刷新,只需要在需要动态刷新的类上加上@RefreshScope注解即可,修改代码如下:
@RestController
@RefreshScope
public class FooBarController {
@Value("${service.name}")
String name;
@GetMapping("/name")
public String getServiceName() {
return name;
}
}
启动consul-provider工程,在浏览器上访问http://localhost:8080/name,页面显示consul-provider。然后
在网页上访问consul的KV存储的管理界面,即http://localhost:8500/ui/dc1/kv,修改config/consul-provider:dev/data的值,修改后的值如下:
service:
name: consul-provider1
server:
port: 8080
此时在在浏览器上访问http://localhost:8080/name,页面显示consul-provider1。可见service.name的最新配置在应用不重启的情况下已经生效。
consul支持的KV存储的Value值不能超过512KB
consul的dev模式,所有数据都存储在内存中,重启Consul的时候会导致所有数据丢失,在正式的环境中,以server模式启动Consul的数据就会会持久化到本地磁盘。