1. Consul 简介
Consul
是 HashiCorp
开发的分布式服务管理框架,提供服务发现、健康检查、配置中心和完整的分布式并行性维护技术。它特别适合应用于小型到大型的分布式集群环境,通过同步机制维护集群内定义好的服务和信息。
官方文档: https://www.consul.io/
代码仓库: https://github.com/hashicorp/consul
核心特性:
- 服务发现:支持服务注册与自动发现,便于其他服务快速找到可用的服务实例。
- 健康检查:内置对服务和节点的健康状态监控,能动态剔除不健康的节点。
- KV 存储:提供键值存储功能,可用于动态配置管理和协调分布式系统的行为。
- 多数据中心支持:天然支持多数据中心部署,确保跨区域服务的高可用性和一致性。
- 安全通信:通过加密和访问控制保障服务间通信的安全性。
应用场景:
- 微服务架构中的服务注册与发现。
- 动态负载均衡和服务路由。
- 分布式系统的配置管理。
- 健康监控与故障转移。
Consul
的设计目标是简化分布式系统的管理难度,并提供一套统一的工具链来提升开发和运维效率。Consul
自推出以来,因其强大的功能和易用性被广泛应用于多个知名项目和企业中, 例如Netflix
在其微服务架构中使用 Consul 进行服务发现与健康检查。
但由于Consul
的特性和功能太多, 而官方的Tutorial
使用了AWS
等云服务进行讲解, 对于国内的小伙伴不是很友好, 因此这里我使用VMWare
虚拟机做一个Consul
的小demo
, 从这个demo
的开发演示中,学习如何使用Consul
进行服务注册与发现。
本章是学习Consul
的第一部分, 因此除了demo
外不会涉及太多琐碎的知识点, 目的是让大家对Consul
的功能、使用方式有一个大体的局具象感知,更详细的使用和原理介绍将在后续章节中进行。
2. 基于虚拟机的 Demo
由于官方的Tutorial
比较复杂, 这里我采用一个极简的demo
进行演示。
2.1 环境准备
环境准备包括以下关键步骤:
2.1.1 VMWare虚拟机的下载与安装**
VMWare Workstation Player
可以从官网免费下载(适用于非商业用途),安装后可用于创建和运行虚拟机。
官方下载地址:https://www.vmware.com/products/workstation-player.html
这里采用
VMWare
而不是WSL
的原因是,VMWare
默认会给创建的虚拟机分配一个随机的IP
地址,且不同虚拟机实例的IP
不同, 而WSL
需要进行一定的配置, 相对麻烦一点。另一方面,VMWare
提供虚拟机的快速克隆, 我们可以在一台虚拟机上部署好所有环境, 然后直接克隆即可, 不需要在4个虚拟机实例上分别布置环境依赖
2.1.2 创建4份 Ubuntu 22.04 Server 实例 安装
创建 4 台 Ubuntu Server 22.04
虚拟机,用于部署 Consul
集群。这里之所以要创建4台虚拟机, 是因为consul
的sever
集群采用的是基于raft
的KV
存储, 因此至少要3个节点, 才能形成server
集群, 另外我们还需要一个client
节点,其是被server
服务的对象。
这里不推荐
Desktop
版本的Ubuntu
, 因为我们要安装4份虚拟机实例, 要是使用Desktop
版本的话, 内存压力会非常大! 同时,VMWare
虚拟机的安装方式我也不介绍了, 默认大家有基础
2.1.3 安装开发工具链(Go、jq 等)
Go
: 用于编译和运行服务注册代码, 我们的服务用Go
写起来最方便, 因为consul
本身使用Go
作为开发语言, 可以直接import
官方源码仓库的api
在go
代码中直接进行集群相关操作。jq
: 用于命令行下对 JSON 数据格式化查看,便于调试和验证Consul
网络接口返回的数据。OpenSSh-Server
: 用于在宿主机和虚拟机之间进行SSH
登录,方便调试和验证, 总不可能在虚拟机这样丑陋的环境里敲命令吧…VSCode
:远程连接虚拟机编写配置文件和代码
至于
SSH
秘钥配置、VSCode
插件配置,jq
的使用方法等, 我就不具体介绍了, 默认大家有一定的基础
2.1.4 获取 Consul 可执行文件
可以直接从 Consul 官网 下载对应操作系统的二进制文件,解压后将 consul
放入系统路径 /usr/local/bin/
即可使用;也可以通过源码编译生成可执行文件。
2.2 启动 agent
2.2.1 agent 的基本概念
这里先对 Consul
中的重要概念 agent
进行介绍:
Consul
以 agent 的形式运行在每一个节点上,agent 可以是 server 或 client 角色。server
负责参与 Raft 协议、维护集群状态和处理请求;client
则负责注册服务、运行健康检查,并将请求转发给 server
集群。
每个 agent
独立运行,通过配置文件(如 .hcl
文件)定义其行为,包括节点名、IP 地址、运行模式、数据目录、通信端口等信息。agent 启动后会尝试加入集群,并持续与其他节点保持通信以维护集群视图和服务状态。
在本 demo
中,我们分别启动了 3 个 server agent
和 1 个 client agent
,构成一个最小化的 Consul 集群。
2.2.2 server agent 配置文件
这里server
的consul aent
的启动命令如下:
1 | consul agent -config-file=server.hcl |
这里的server.hcl
是配置文件, 其内容如下:
1 | datacenter = "dc1" |
这里说明如下:
datacenter
: 设置当前节点所属的数据中心名称为dc1
。Consul 支持多数据中心部署,该配置用于标识该节点归属于哪个数据中心。数据中心是部署的最高级别单位,通常对应于一个物理数据中心或云提供商的一个区域
-node_name
: 指定当前Consul
节点(agent
)的唯一名称,在集群中通过这个名称来识别不同的节点。data_dir
: 定义Consul
持久化数据的存储目录,例如节点状态、服务信息和Raft
日志等都保存在此路径下。bind_addr
: 设置当前节点与其他Consul agent
通信时绑定的 IP 地址。不需要指定端口, 内部会指定一个默认端口。client_addr
: 指定客户端接口监听的地址,用于接收 HTTP/DNS/gRPC 等客户端请求。设置为0.0.0.0
表示允许从任意 IP 访问 API 接口。server = true
: 表示该节点是以 server 角色运行。server
是Consul
集群的核心组件,负责参与Raft
协议、维护集群一致性等关键任务。bootstrap_expect
: 声明集群中预期加入的server
节点总数。当第一个server
启动时,它会等待直到有 3 个server
加入后才进行Raft
初始化,从而避免脑裂问题。ui_config
: 启用内置 Web UI 界面,可以通过浏览器访问Consul
的可视化界面,查看节点、服务、健康状态等信息。log_level
: 设置日志输出级别为INFO
,即显示正常运行日志。也可以设为DEBUG
或ERROR
来控制日志详细程度。retry_join
: 配置自动重试加入的其他Consul
节点地址。在启动过程中,如果首次连接失败,Consul
会持续尝试与这些节点建立连接,以加入集群。此处列出的是其他两个server
节点的 IP 地址。
注意:每个
server
节点的bind_addr
和node_name
应根据实际机器进行修改,而retry_join
列表应包含除自身外的所有 server 节点地址。
2.2.3 client agent 配置文件
这里client
的consul aent
的启动命令如下:
1 | consul agent -config-file=client.hcl |
这里的client.hcl
是配置文件, 其内容如下:
1 | datacenter = "dc1" |
client
这里的配置文件内容和 server
配置文件基本一致,只是去掉了 server = true
和 bootstrap_expect
这两个配置项。并且需要指定整个server
的 retry_join
列表,以包含所有 server
节点地址。
2.2.4 启动集群后的状态
在3个节点启动server agnet
以及1个节点启动client agent
后, 我们的集群就已经正常搭建好了。可以在任意一个节点上云霄下面的命令查看集群节点状态:
1 | l$ consul members |
其输出包含健康状态、IP、类型等信息。
我们也可以只查看server
这样参与选举的节点信息:
1 | $ consul operator raft list-peers |
这是我们可以杀掉其中某个``server`节点,然后观察集群状态变化:
1 | $ consul operator raft list-peers |
发现掉了一个leader
节consul-server-2
点之后触发了重新选举, 集群仍然可以正常工作(这方面的只是可以搜索关键字raft
了解)
当我们重启consul-server-2
后再次查询:
1 | $ consul operator raft list-peers |
其能够在此加入集群。
你也可以测试杀掉
client
节点试试看看
2.3 服务注册与发现
现在我们有了集群, 但还没有服务, 我们需要先编写一个服务注册的代码, 然后运行这个服务并注册
2.3.1 Go 服务代码
这里我们用Go
写一段简单的代码:
1 | package main |
这段 Go
代码实现了一个简单的 HTTP Web
服务,主要作用是监听本地的 5000
端口,并对所有访问根路径 / 的请求返回 “Hello from service A!” 的响应。
写完之后我们直接:
1 | go build -o app |
这段代码当然是在
consul-client-1
这个节点上编写并运行的。
3.2 命令行方式注册服务
我们现在在consul-client-1
这个节点已经运行了一个服务, 我们现在需要将其注册到consul
集群中。Consul
支持通过http
接口发送注册服务的请求, 这里我们把Post
请求的body
写在一个json
文件里,然后通过curl
发送请求:
service.json:
1 | { |
这里重点讲解Check
, 其就是规定了Consul
通过什么网络接口判断服务是否健康。
发送请求:
1 | curl --request PUT --data @service.json http://127.0.0.1:8500/v1/agent/service/register |
8500 是
consul
的http
端口
然后我们就可以在consul
集群中看到这个服务了:
1 | $ consul catalog services |
另一方面, 我们也可以通过http
查询服务的具体健康信息:
1 | $ curl http://localhost:8500/v1/health/service/service-a | jq |
原始的结果比较长, 这里我省略了部分, 需要重点关注的就是Checks
字段的Status
, 案例的Status
字段为passing
, 表示服务正常。
现在我们杀掉服务:
1 | $ kill -9 $(ps aux | grep 'app' | awk '{print $2}') |
此时返回的结果中:
1 | { |
Status
字段为critical
, 表示服务已经挂了。
当我们重新启动服务后再次检查, Status
字段变为passing
, 这就是Consul
对服务状态维护的检测功能
3.3 Go 代码引入第三方库注册服务
尽管我们也可以通过http
接口注册服务, 但Consul
提供了SDK
来简化操作, 我们可以引入第三方库来注册服务,这样运行代码就可以自动进行注册服务等基础的操作, 不需要额外通过人工命令行的方式进行操作。
安装 SDK:
1 | go get github.com/hashicorp/consul/api |
服务代码:
1 | package main |
现在我们编译后运行服务,其会自动进行注册
3 小结
通过本章的实践,我们完成了以下关键内容:
了解 Consul 的基本概念与核心功能
Consul 是一个分布式服务管理工具,提供服务发现、健康检查、KV 存储、多数据中心支持和安全通信等能力。它适用于从单机开发环境到大规模生产集群的各种场景。搭建 Consul 集群环境
我们基于 VMWare 创建了 4 台 Ubuntu 虚拟机,其中 3 台作为 server agent 组成 Raft 集群,1 台作为 client agent 接入集群。通过.hcl
配置文件分别配置其角色和网络信息,并成功启动了 Consul 集群。理解 Agent 的运行机制
Consul 以 agent 的形式运行在每个节点上,server agent 负责集群状态维护,client agent 负责注册服务并转发请求。agent 启动后会持续与其他节点通信,维护集群一致性。配置 Consul Server 与 Client
详细讲解了server.hcl
和client.hcl
配置文件中各个参数的作用,包括数据中心设置、节点名称、数据目录、监听地址、集群加入方式等,为搭建高可用集群打下基础。验证集群状态与容错能力
使用consul members
和consul operator raft list-peers
查看集群成员与 Raft 状态。测试 kill 掉某个 server 节点后,集群仍能正常进行 leader 选举和状态同步,体现了 Consul 的高可用特性。实现服务注册与健康检查
编写了一个简单的 HTTP Web 服务,并通过两种方式将其注册到 Consul:- 命令行方式:使用
curl
发送 JSON 请求注册服务,并配置健康检查。 - Go SDK 方式:引入
github.com/hashicorp/consul/api
包,在代码中自动完成服务注册与健康上报。
- 命令行方式:使用
演示 Consul 的服务健康监测能力
当服务正常运行时,Consul 显示其状态为passing
;当服务被 kill 掉后,Consul 检测到异常并将状态变为critical
,实现了对服务状态的动态感知。
本章通过一个极简但完整的 Demo,展示了 Consul 在服务注册与发现中的核心作用,也为我们后续深入学习其原理和高级用法打下了良好基础。
但我们目前还缺少对这个服务的具体应用,Consul
是一个功能非常多的微服务管理框架, 不同微服务简可以通过Consul
机械能各种类型的通信, 这些将在后续章节中进一步介绍。(如果我不鸽。。。。。。)