Consul定义
Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。
Consul特点
- Consul 采用 Raft 一致性协议算法来保证服务的高可用;
- 使用 GOSSIP 协议管理成员和广播消息;
- 服务注册与发现: Consul 同时支持 DNS 或者 HTTP 两种接口进行服务注册和服务发现;
- 支持健康检查: Consul 可以通过定期运行脚本进行健康检查;
- 支持多数据中心方案:支持多机房配置,可以避免单机房单点故障;
- 简易安装部署:安装包仅包含一个二进制文件,支持跨平台运行,可与Docker 等轻量级容器实现无缝配合;
- 官方提供 web 管理界面, etcd 无此功能;
Consul 架构
Consul架构,如下图所示:
图片上 datacenter 分成上下两个部分, 但是这两个部分又不是完全隔离的,他们之间通过 WAN GOSSIP 进行报文交互。
单个 datacenter 中, 节点被划分成两种颜色, 红色的 server, 紫色的 client, 他们之间通过 GRPC 进行通信(业务数据)。
Server:
- 参与共识仲裁(raft);
- 存储机器状态(日志存储);
- 处理查询;
- 维护周边(LAN/WAN) 节点之间的关系;
Client :
- 负责通过该节点注册到 Consul 微服务的健康检查;
- 将客户端的注册请求和查询转换为 server 的 RPC 请求;
- 维护周边各节点(LAN/WAN) 的关系;
Consul原理
核心原理在于两点:
- 集群信息之间的高效同步机制,保障拓扑变动与控制信号的及时同步。
- server 集群内日志存储的强一致性。
他们主要基于两个协议来实现
- Gossip 协议,在集群内消息传递
- 使用 raft 协议保障日志的一致性。
Gossip协议
传统的监控,如ceilometer,由于每个节点都会向server报告状态,随着节点数量的增加server的压力 随之增大。在所有的Agent之间(包括服务器模式和普通模式)运行着Gossip协议。服务器节点和普通 Agent都会加入这个Gossip集群,收发Gossip消息。每隔一段时间,每个节点都会随机选择几个节点发 送Gossip消息,其他节点会再次随机选择其他几个节点接力发送消息。这样一段时间过后,整个集群都 能收到这条消息。
示意图如下。
RAFT一致性算法
为了实现集群中多个ConsulServer中的数据保持一致性,consul使用了基于强一致性的RAFT算法。 在Raft中,任何时候一个服务器可以扮演下面角色之一:
- Leader: 处理所有客户端交互,日志复制等,一般一次只有一个Leader.
- Follower: 类似选民,完全被动
- Candidate(候选人): 可以被选为一个新的领导人。
Leader全权负责所有客户端的请求,以及将数据同步到Follower中(同一时刻系统中只存在一个 Leader)。Follower被动响应请求RPC,从不主动发起请求RPC。Candidate由Follower向Leader转换 的中间状态。
Consul使用
Consul 支持健康检查,并提供了 HTTP 和 DNS 调用的API接口完成服务注册,服务发现,以及K/V存储 这些功能。接下来通过发送HTTP请求的形式来了解一下Consul
1.注册服务
通过postman发送put请求到
http://192.168.74.101:8500/v1/catalog/register地址可以完成服务注册
{
"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
}
}
2.服务查询
通过postman发送get请求到
http://192.168.74.101:8500/v1/catalog/services查看所有的服务列表
通过postman发送get请求到
http://192.168.74.101:8500/v1/catalog/service/服务名查看具体的服务详情
3.服务删除
通过postman发送put请求到
http://192.168.74.101:8500/v1/catalog/deregister删除服务
{
"Datacenter": "dc1",
"Node": "node01",
"ServiceID": "mysql-01"
}
Consul的KV存储
可以参照Consul提供的KV存储的API完成基于Consul的数据存储
- key值中可以带/, 可以看做是不同的目录结构。
- value的值经过了base64_encode,获取到数据后base64_decode才能获取到原始值。数据不能大 于512Kb
- 不同数据中心的kv存储系统是独立的,使用dc=?参数指定。
基于consul的服务注册
案例准备
(1)复制一份新的工程进行配置
拷贝一份新的工程,起名为 shop_consul_parent ,并导入相关的子模块
(2)修改微服务的相关pom文件
修改每个微服务的pom文件,添加SpringCloud提供的基于Consul的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
其中
spring-cloud-starter-consul-discovery 是SpringCloud提供的对consul支持的相关依赖。
spring-boot-starter-actuator 适用于完成心跳检测响应的相关依赖。
配置服务注册
修改每个微服务的application.yml配置文件,添加consul服务发现的相关配置信息
spring:
...省略
cloud:
consul: #consul相关配置
host: 192.168.74.101 #ConsulServer请求地址
port: 8500 #ConsulServer端口
discovery:
#是否注册
register: true
#实例ID
instance-id: ${spring.application.name}-1
#服务实例名称
service-name: ${spring.application.name}
#服务实例端口
port: ${server.port}
#健康检查路径
healthCheckPath: /actuator/health
#健康检查时间间隔
healthCheckInterval: 15s
#开启ip地址注册
prefer-ip-address: true
#实例的请求ip
ip-address: ${spring.cloud.client.ip-address}
其中 spring.cloud.consul 中添加consul的相关配置
- host:表示Consul的Server的请求地址
- port:表示Consul的Server的端口
- discovery:服务注册与发现的相关配置 instance-id : 实例的唯一id(推荐必填),spring cloud官网文档的推荐,为了保证生成一 个唯一的id ,也可以换成 ${spring.application.name}:${spring.cloud.client.ipAddress} prefer-ip-address:开启ip地址注册 ip-address:当前微服务的请求ip
在控制台中查看服务列表
打开ConsulServer的管理控制台,可以发现三个微服务已经全部注册到Consul中了。
基于consul的服务发现
由于SpringCloud对Consul进行了封装。对于在消费者端获取服务提供者信息和Eureka是一致的。同样 使用 DiscoveryClient 完成调用获取微服务实例信息
mikechen睿哥
mikechen睿哥,十余年BAT架构经验,资深技术专家,就职于阿里、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》