概述
- 主要应用场景:服务发现、服务隔离、服务配置
- HashiCorp公司开发,使用Go语言编写
- 内置了服务注册与发现框架、分布式一致性协议实现、健康检测、Key/Value存储、多数据中心方案
- 使用Raft算法来保证一致性,比复杂的Paxos算法更直接,相比较而言,zookeeper采用的是Paxos,而etcd使用的则是Raft
- 支持http和dns协议接口
- 官方提供web管理界面
- Consul是强一致性(CP):注册会比Eureka慢点,要求过半数节点写入成功才认为注册成功。另外,当leader挂掉的时候,重新选举期间整个consul不可用,保持强一致性牺牲了可用性。
下载安装
- 下载地址:https://www.consul.io/downloads.html
- 根据自己的电脑系统下载对应的文件,我就下载window的版本,直接安装使用。
- 我将下载好的文件解压到D:\software\consul目录下,然后运行consul agent -dev -client=0.0.0.0命令启动consul
- 到浏览器中输入http://127.0.0.1:8500/,即可登录consul的后台管理界面
到这里就可以开始使用consul了
服务注册
consul支持通过http或者dns的方式进行注册。我们比较关注的是http,来看看是怎么注册的。
- 首先就是找到需要发送注册的接口:http://ip:8500/v1/catalog/register
- 接口数据,json形式:
{
"Datacenter":"dc1",
"Node":"node01",
"Address":"192.168.74.102",
"Service":{
"ID":"mysql-01",
"Service":"mysql",
"tags":["master","v1"],
"Address":"192.168.74.102",
"Port":3306
}
}
- 测试,我这里使用一个可以模拟发送http请求的软件—苏飞开发助手,发送的是PUT请求
测试成功,可以看出,consul的集成度极高,可以进行很简便的开发。另外还有服务获取接口等,有兴趣可以百度一下,这边就不作展示了,在springcloud中,引入依赖就已经把这一切封装好了。
springcloud中引入consul
服务的提供者和一个服务的消费者
我这里就效仿Eureka,使用springboot搭建两个最简单的服务,里面除了是一个普通的springboot项目外,什么都还不是
引入consul操作相关依赖
<!-- springcloud 提供的对基于consul 的服务发现 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- acuator 的健康检查 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置
server:
port: 9001 #端口
spring:
application:
name: product-service #服务名称
#配置consul
cloud:
consul:
host: 127.0.0.1 #注册中心的主机ip地址
port: 8500 #注册中心的端口
discovery:
#是否需要注册
register: true
#注册的实例id(唯一标志)
instance-id: ${spring.application.name}-1
#服务的名称
service-name: ${spring.application.name}
#服务的请求端口
port: ${server.port}
#指定开启ip地址注册
prefer-ip-address: true
#当前服务的请求ip
ip-address: ${spring.cloud.client.ip-address}
服务调用
与服务提供者一样,将服务消费者配置好,然后在服务消费者中调用服务。同样的,我们需要restTemplate,另外,在这个consul依赖包中也集成了对ribbon的支持,因此,可以这样处理restTemplate
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
然后使用restTemplate从服务提供者获取相关数据
//注入restTemplate
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/get/{id}",method = RequestMethod.GET)
public String get(@PathVariable Long id){
//通过instance里面的信息,组合成url,访问服务接口
return restTemplate.getForObject("http://product-service/product/getProduct/"+id,String.class);
}
可自行测试