一、Consul简介
Consul是由HashiCorp基于Go语言开发的支持多数据中心的分布式高可用服务发布和注册软件, 采用Raft算法保持服务的一致性, 且支持健康检查,Consul和Eureka的侵入式服务中心不同的是, Consul是以独立的软件形式运行, 对项目侵入性小, 更方便部署。
Consul是微服务架构中,解决服务发现、配置中心的分布式中间件。
二、Consul服务注册
consul支持两种方式注册服务信息,使用配置文件或者http接口注册服务。
第一种方式:基于配置文件
# 基于配置文件的服务注册方式,是consul官方推荐的方式,因为这种方式对我们微服务应用无侵入,就是不需要写代码调consul的接口注册服务信息。
1、定义服务
为方便管理,服务定义配置文件统一为json格式。
例如:定义一个名字叫node-export的服务。
[root@node2 ~]# vim /etc/consul.d/node.json
{
"service": {
"id": "1",
"name": "node-export-node1",
"tags": ["node-export"],
"address": "192.168.11.197",
"port": 9100
}
}
服务配置文件名,可以随便取,通常以服务名命名。
配置文件参数说明:
· name - 服务名
· tags - 可以为服务打上标签,是个字符串数组,查询服务的时候可以用来过滤
· port - 服务的端口
· address - 服务的ip地址,可选,一般不用填写,注册的时候agent会加上。
2、注册服务
# 重新加载配置
[root@node2 ~]# consul reload
Configuration reload triggered
3、查询注册的服务
3.1、Web查看注册的服务
3.2、命令行查看
[root@node2 ~]# consul catalog services
consul
node-export-node1
4、删除已注册服务
# 输入下面命令,会删除注册的服务信息,永久删除需要同时删掉本地的服务的配置文件。
[root@node2 ~]# consul services deregister -id=1
Deregistered service: 1
第二种:使用接口注册服务
# 通过http接口注册服务,一般不推荐,不如配置文件方便,如果你想通过api注册,可以参考官方服务注册api接口文档:https://www.consul.io/api/catalog.html
1、注册服务
[root@node2 ~]# curl -X PUT -d '{
"id": "2",
"name": "node-export-node2",
"address": "192.168.11.198",
"port": 9100,
"tags": ["node-exporter"]
}' http://192.168.11.198:8500/v1/agent/service/register
2、查询注册的服务
2.1、Web查看注册的服务
2.2、命令行查看
[root@node2 ~]# consul catalog services
consul
node-export-node1
node-export-node2
3、删除已注册服务
[root@node2 ~]# curl --request PUT http://127.0.0.1:8500/v1/agent/service/deregister/2
三、Consul服务查询
Consul支持两种接口查询我们注册的服务信息,API或者DNS查询。
1、通过API接口查询
1)查询指定服务名
API查询格式:http://localhost:8500/v1/catalog/service/服务名
例如:查询服务名为node-export-node1详情信息
[root@node2 ~]# curl http://localhost:8500/v1/catalog/service/node-export-node1?pretty
返回结果:
[
{
"ID": "c869febb-4c23-cc8e-a8e1-90c7fc5e1e27",
"Node": "node2", # 节点名称
"Address": "192.168.11.198", # 服务地址
"Datacenter": "consul-cluster", # 数据中心名称
"TaggedAddresses": {
"lan": "192.168.11.198",
"lan_ipv4": "192.168.11.198",
"wan": "192.168.11.198",
"wan_ipv4": "192.168.11.198"
},
"NodeMeta": {
"consul-network-segment": ""
},
"ServiceKind": "",
"ServiceID": "1",
"ServiceName": "node-export-node1", # 服务名
"ServiceTags": [
"node-export"
],
"ServiceAddress": "192.168.11.197",
"ServiceTaggedAddresses": {
"lan_ipv4": {
"Address": "192.168.11.197",
"Port": 9100
},
"wan_ipv4": {
"Address": "192.168.11.197",
"Port": 9100
}
},
"ServiceWeights": {
"Passing": 1,
"Warning": 1
},
"ServiceMeta": {},
"ServicePort": 9100, # 服务端口
"ServiceSocketPath": "",
"ServiceEnableTagOverride": false,
"ServiceProxy": {
"Mode": "",
"MeshGateway": {},
"Expose": {}
},
"ServiceConnect": {},
"CreateIndex": 765,
"ModifyIndex": 765
}
]
2)查询注册中心的服务注册清单
[root@node2 ~]# curl http://localhost:8500/v1/catalog/services?pretty
返回结果:
{
"consul": [],
"node-export-node1": [
"node-export"
],
"node-export-node2": [
"node-exporter"
],
"node-export-node3": [
"node-exporter"
]
}
2、通过DNS查询
consul支持通过dns查询服务信息,dns只能返回可用的服务地址。
2.1、Centos安装dig
[root@node2 ~]# yum -y install bind-utils
1)例如:查询consul服务的地址。
[root@node2 ~]# dig @127.0.0.1 -p 8600 consul.service.consul
返回结果:
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.13 <<>> @127.0.0.1 -p 8600 consul.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40552
;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;consul.service.consul. IN A
;; ANSWER SECTION:
consul.service.consul. 0 IN A 192.168.11.197
consul.service.consul. 0 IN A 192.168.11.199
consul.service.consul. 0 IN A 192.168.11.198
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Thu Apr 06 10:35:18 CST 2023
;; MSG SIZE rcvd: 98
注:上面dig命令默认查询的是DNS的A记录,只能查询到IP地址,查询不到端口号,我们可以通过查询DNS的SRV记录,获取完整的服务地址(ip和端口号)
参数说明:
- @127.0.0.1:指定dns服务器地址,就是我们consul的agent地址,本地安装了agent使用127.0.0.1即可
- -p:指定dns服务的端口,consul默认使用的是8600
consul.service.consul是需要查询的域名。
consul服务的域名规则:服务名.service.consul
2)查询SRV记录
[root@node2 ~]# dig @127.0.0.1 -p 8600 consul.service.consul SRV
返回结果:
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.13 <<>> @127.0.0.1 -p 8600 consul.service.consul SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62817
;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 7
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;consul.service.consul. IN SRV
;; ANSWER SECTION:
consul.service.consul. 0 IN SRV 1 1 8300 node2.node.consul-cluster.consul.
consul.service.consul. 0 IN SRV 1 1 8300 node1.node.consul-cluster.consul.
consul.service.consul. 0 IN SRV 1 1 8300 node3.node.consul-cluster.consul.
;; ADDITIONAL SECTION:
node2.node.consul-cluster.consul. 0 IN A 192.168.11.198
node2.node.consul-cluster.consul. 0 IN TXT "consul-network-segment="
node1.node.consul-cluster.consul. 0 IN A 192.168.11.197
node1.node.consul-cluster.consul. 0 IN TXT "consul-network-segment="
node3.node.consul-cluster.consul. 0 IN A 192.168.11.199
node3.node.consul-cluster.consul. 0 IN TXT "consul-network-segment="
;; Query time: 1 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Thu Apr 06 10:40:13 CST 2023
;; MSG SIZE rcvd: 362
四、Consul健康检查
consul健康检查机制运行在consul client中,会定期的根据服务的健康检查配置,去检测服务是否正常,如果服务异常,就将服务的实例标记为不用,如果恢复了,就标记为可用。
健康检查基本配置格式,是在服务定义配置中,增加checks字段,配置健康检查。
{
"service": {
"id": "1",
"name": "node-export-node1",
"tags": ["node-export"],
"address": "192.168.11.197",
"port": 9100,
"check": [
{
...检查内容...
}
]
}
}
consul健康检查有多种方式,具体的配置,以下会一一演示。
1、基于http请求
定时Get请求方式访问url,请求返回状态码为200代表正常,否则代表异常。
例子:
{
"service": {
"id": "1",
"name": "node-export-node1",
"tags": ["node-export"],
"address": "192.168.11.197",
"port": 9100,
"check": [
{
"id": "http", // 健康检查项目ID
"name": "HTTP API on Port 9100", // 检查名称
"http": "http://192.168.11.197:9100/metrics", // 访问url地址
"tls_skip_verify": false, // 关闭tls验证
"method": "GET", // 设置http请求方式
"interval": "10s", // 建立连接的时间间隔
"timeout": "1s" // 检查超时时间
}
]
}
}
2、基于tcp请求
基于tcp请求方式,定时向指定的地址建立tcp连接,连接成功就代表服务正常,否则代表异常。
例子:
{
"service": {
"id": "1",
"name": "node-export-node1",
"tags": ["node-export"],
"address": "192.168.11.197",
"port": 9100,
"check": [
{
"id": "tcp", // 健康检查项目ID
"name": "node exporter TCP on Port 9100", // 检查名称
"tcp": "192.168.11.197:9100", // TCP检测IP和端口地址
"interval": "10s", // 建立连接的时间间隔
"timeout": "1s" // 检查超时时间
}
]
}
}
3、基于grpc请求
如果微服务是基于grpc协议,可以使用grpc协议检测服务是否正常。
例子:
{
"service": {
"id": "8",
"name": "web",
"tags": ["spring-web"],
"address": "192.168.11.197",
"port": 8080,
"check": [
{
"id": "grpc", // 健康检查项目ID
"name": "Service Health Status", // 检查名称
"grpc": "192.168.11.197:8080", // grpc地址
"grpc_use_tls": true, // 开启tls验证
"interval": "10s", // 建立连接的时间间隔
"timeout": "1s" // 检查超时时间
}
]
}
}
4、基于命令或脚本
consul支持定期执行一个命令或者脚本,来检测服务是否正常;Consul通过检测命令退出状态判断服务是否正常,命令退出状态0代表正常,其他代表异常。
例子1:基于命令
{
"service": {
"id": "web",
"name": "web",
"tags": ["web"],
"address": "192.168.11.197",
"port": 80,
"check": [
{
"id": "command",
"name": "Check Service Code",
"args": ["curl","localhost"],
"interval": "10s"
}
]
}
}
例子2:基于脚本
{
"service": {
"id": "web",
"name": "web",
"tags": ["web"],
"address": "192.168.11.197",
"port": 80,
"check": [
{
"id": "script",
"name": "Shell Check Status",
"args": ["/data/scripts/check_service_status.sh"],
"interval": "10s",
"timeout": "1s"
}
]
}
}
5、基于Docker
输出限制在4K以内,输出大于4K将截断。
例子:
{
"service": {
"id": "web",
"name": "web",
"tags": ["web"],
"address": "192.168.11.197",
"port": 80,
"check": [
{
"id": "docker",
"name": "Docker Memory utilization",
"docker_container_id": "86432ee84a9f",
"shell": "/bin/bash",
"script": ["/data/scripts/check_memory.sh"],
"interval": "10s"
}
]
}
}
注意:为了安全考虑,如果健康检查使用执行命令方式,在启动consul的时候支持下面两种参数:
- -enable-script-checks 允许通过配置文件和http api注册的服务,执行命令检查健康状态
- -enable-local-script-checks 禁止通过http api注册的服务,执行命令检查健康状态,只允许通过配置文件注册的服务,执行命令。
若文章图片、下载链接等信息出错,请在评论区留言反馈,博主将第一时间更新!如本文“对您有用”,欢迎随意打赏,谢谢!
评论