一、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注册的服务,执行命令检查健康状态,只允许通过配置文件注册的服务,执行命令。
若文章图片、下载链接等信息出错,请在评论区留言反馈,博主将第一时间更新!如本文“对您有用”,欢迎随意打赏,谢谢!
 
					 
					 
							
 
												

评论