Consul是一个网络工具,提供了一个功能齐全的service-mesh控制层,服务发现,配置,和分区。
一.安装
1.安装consul
下载consul,这里我下载的是linux版本的,
下载下来的是一个zip压缩文件,解压后得到一个consul二进制文件,解压后,确保consul文件可被环境变量访问
# 解压consul
$ unzip consul_1.7.2_linux_amd64.zip
# 查看PATH变量
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
#我这里把consul文件放在/usr/local/bin目录下,保证consul可以访问到
$ mv consul /usr/local/bin
2.验证是否安装成功,在命令行中输入consul
$ consul
usage: consul [--version] [--help] <command> [<args>]
Available commands are:
agent Runs a Consul agent
event Fire a new event
...
如果您得到一个无法找到consul的错误,说明你的PATH环境变量没有正确设置。请确保您的PATH变量包含安装了consul的目录
二.运行consul代理
安装领事后,你需要启动consul代理。以下将以开发模式运行consul代理,这种模式不安全,也不具有可伸缩性,但是可以让你轻松体验consul的大多数功能,而不需要额外的配置。你还将知道如何优雅地关闭consul代理
服务端和客户端代理
在生产环境中,可以在服务器或客户端模式下运行每个consul代理。每个consul数据中心必须至少有一个服务器,负责维护consul的状态。这包括关于其他consul服务器和客户端的信息、可用于发现的服务以及允许哪些服务与哪些其他服务进行通信。
为了确保即使服务器发生故障也能维护consul的状态,您应该始终在生产环境中运行3或5个服务器。服务器的奇数(不超过5个)在性能和容错之间取得平衡
非服务器代理在客户端模式下运行。客户机是一个轻量级进程,它注册服务、运行健康检查并将查询转发到服务器。客户端必须运行在运行服务的consul数据中心的每个节点上,因为客户端是服务健康状况的真实来源。
当你准备在生产使用时,可以在部署指南中找到关于服务器和客户端的生产部署的更多指导。现在,让我们以开发模式启动本地代理,这是一种内存服务器模式,为便于使用启用了一些公共特性(尽管存在安全风险),并且关闭了所有持久性选项。
启动consul代理
在开发模式下启动consul代理。
$ consul agent -dev
==> Starting Consul agent...
Version: 'v1.7.2'
Node ID: '58b5abd3-4071-f5d5-bf6d-d87e0e7fb079'
Node name: 'alias'
Datacenter: 'dc1' (Segment: '<all>')
Server: true (Bootstrap: false)
Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600)
Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false
==> Log data will now stream in as it occurs:
2020-03-18T20:14:44.575+0800 [DEBUG] agent: Using random ID as node ID: id=58b5abd3-4071-f5d5-bf6d-d87e0e7fb079
2020-03-18T20:14:44.575+0800 [DEBUG] agent.tlsutil: Update: version=1
2020-03-18T20:14:44.576+0800 [DEBUG] agent.tlsutil: OutgoingRPCWrapper: version=1
2020-03-18T20:14:44.576+0800 [INFO] agent.server.raft: initial configuration: index=1 servers="[{Suffrage:Voter ID:58b5abd3-4071-f5d5-bf6d-d87e0e7fb079 Address:127.0.0.1:8300}]"
2020-03-18T20:14:44.576+0800 [INFO] agent.server.serf.wan: serf: EventMemberJoin: alias.dc1 127.0.0.1
2020-03-18T20:14:44.576+0800 [INFO] agent.server.serf.lan: serf: EventMemberJoin: alias 127.0.0.1
2020-03-18T20:14:44.577+0800 [INFO] agent: Started DNS server: address=127.0.0.1:8600 network=udp
2020-03-18T20:14:44.577+0800 [INFO] agent.server.raft: entering follower state: follower="Node at 127.0.0.1:8300 [Follower]" leader=
2020-03-18T20:14:44.579+0800 [INFO] agent.server: Adding LAN server: server="alias (Addr: tcp/127.0.0.1:8300) (DC: dc1)"
2020-03-18T20:14:44.579+0800 [INFO] agent.server: Handled event for server in area: event=member-join server=alias.dc1 area=wan
2020-03-18T20:14:44.580+0800 [INFO] agent: Started DNS server: address=127.0.0.1:8600 network=tcp
2020-03-18T20:14:44.581+0800 [INFO] agent: Started HTTP server: address=127.0.0.1:8500 network=tcp
2020-03-18T20:14:44.581+0800 [INFO] agent: started state syncer
==> Consul agent running!
2020-03-18T20:14:44.581+0800 [INFO] agent: Started gRPC server: address=127.0.0.1:8502 network=tcp
2020-03-18T20:14:44.614+0800 [WARN] agent.server.raft: heartbeat timeout reached, starting election: last-leader=
2020-03-18T20:14:44.614+0800 [INFO] agent.server.raft: entering candidate state: node="Node at 127.0.0.1:8300 [Candidate]" term=2
2020-03-18T20:14:44.615+0800 [DEBUG] agent.server.raft: votes: needed=1
2020-03-18T20:14:44.615+0800 [DEBUG] agent.server.raft: vote granted: from=58b5abd3-4071-f5d5-bf6d-d87e0e7fb079 term=2 tally=1
2020-03-18T20:14:44.615+0800 [INFO] agent.server.raft: election won: tally=1
2020-03-18T20:14:44.615+0800 [INFO] agent.server.raft: entering leader state: leader="Node at 127.0.0.1:8300 [Leader]"
2020-03-18T20:14:44.615+0800 [INFO] agent.server: cluster leadership acquired
启动日志显示,consul代理已经启动,并正在传输一些日志数据。他们还报告说,代理正在作为服务器运行,并声称为leader。此外,本地代理已被标记为数据中心的健康成员。
Datacenter Members
在新的终端窗口中运行consul members命令,检查consul数据中心的成员关系。输出列出了数据中心中的代理。稍后我们将介绍如何将领事代理连接在一起,但目前只有一个成员(当前的机器)。
$ consul members
Node Address Status Type Build Protocol DC Segment
alias 127.0.0.1:8301 alive server 1.7.2 2 dc1 <all>
输出显示出你的代理、IP地址、健康状态、代理在数据中心中的角色以及一些版本信息。你可以使用-detailed
标记来发现额外的元数据。
members命令针对领事客户端运行,后者通过gossip协议获取信息。客户端拥有的信息最终是一致的,但是在任何时候,它的视图都可能与服务器上的状态不完全匹配。要获得一个非常一致的视图,可以查询HTTP API,它将请求转发给领事服务器。
$ curl localhost:8500/v1/catalog/nodes
[
{
"ID": "0bb70c85-c52d-e10a-07c8-6b8451e5dee4",
"Node": "alias",
"Address": "127.0.0.1",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "127.0.0.1",
"lan_ipv4": "127.0.0.1",
"wan": "127.0.0.1",
"wan_ipv4": "127.0.0.1"
},
"Meta": {
"consul-network-segment": ""
},
"CreateIndex": 10,
"ModifyIndex": 11
}
]
除了HTTP API之外,你还可以使用DNS interface 来发现节点。除非你启用了缓存,否则DNS接口将把你的查询发送到consul服务器。要执行DNS查找,你必须指向consul代理的DNS服务器,该服务器默认在端口8600上运行。稍后将更详细地介绍DNS条目的格式(例如judiths - mbp .node.consul)。
$ dig @127.0.0.1 -p 8600 Judiths-MBP.node.consul
; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> @127.0.0.1 -p 8600 Judiths-MBP.node.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 30453
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;Judiths-MBP.node.consul. IN A
;; AUTHORITY SECTION:
consul. 0 IN SOA ns.consul. hostmaster.consul. 1584534749 3600 600 86400 0
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Wed Mar 18 20:32:29 CST 2020
;; MSG SIZE rcvd: 102
停止运行代理
使用consul leave
命令停止cosnul代理。这将优雅地停止代理,使其从consul数据中心退出并关闭。
$ consul leave
Graceful leave complete
如果切换回带有consul流日志输出的窗口,则日志表明consul代理离开了数据中心。
2020-03-18T20:34:45.509+0800 [INFO] agent.server: server starting leave
2020-03-18T20:34:45.509+0800 [INFO] agent.server.serf.wan: serf: EventMemberLeave: alias.dc1 127.0.0.1
2020-03-18T20:34:45.509+0800 [INFO] agent.server: Handled event for server in area: event=member-leave server=alias.dc1 area=wan
2020-03-18T20:34:45.509+0800 [INFO] agent.server.router.manager: shutting down
2020-03-18T20:34:48.509+0800 [INFO] agent.server.serf.lan: serf: EventMemberLeave: alias 127.0.0.1
2020-03-18T20:34:48.509+0800 [INFO] agent.server: Removing LAN server: server="alias (Addr: tcp/127.0.0.1:8300) (DC: dc1)"
2020-03-18T20:34:48.509+0800 [WARN] agent.server: deregistering self should be done by follower: name=alias
2020-03-18T20:34:48.655+0800 [ERROR] agent.server.autopilot: Error updating cluster health: error="error getting server raft protocol versions: No servers found"
2020-03-18T20:34:50.655+0800 [ERROR] agent.server.autopilot: Error updating cluster health: error="error getting server raft protocol versions: No servers found"
2020-03-18T20:34:51.509+0800 [INFO] agent.server: Waiting to drain RPC traffic: drain_time=5s
2020-03-18T20:34:52.655+0800 [ERROR] agent.server.autopilot: Error updating cluster health: error="error getting server raft protocol versions: No servers found"
2020-03-18T20:34:54.655+0800 [ERROR] agent.server.autopilot: Error updating cluster health: error="error getting server raft protocol versions: No servers found"
2020-03-18T20:34:56.509+0800 [INFO] agent: Requesting shutdown
2020-03-18T20:34:56.509+0800 [INFO] agent.server: shutting down server
2020-03-18T20:34:56.509+0800 [DEBUG] agent.leader: stopping routine: routine="CA root pruning"
2020-03-18T20:34:56.509+0800 [DEBUG] agent.leader: stopped routine: routine="CA root pruning"
2020-03-18T20:34:56.509+0800 [INFO] agent: consul server down
2020-03-18T20:34:56.510+0800 [INFO] agent: shutdown complete
2020-03-18T20:34:56.510+0800 [DEBUG] agent.http: Request finished: method=PUT url=/v1/agent/leave from=127.0.0.1:57862 latency=11.000960126s
2020-03-18T20:34:56.510+0800 [INFO] agent: Stopping server: protocol=DNS address=127.0.0.1:8600 network=tcp
2020-03-18T20:34:56.510+0800 [INFO] agent: Stopping server: protocol=DNS address=127.0.0.1:8600 network=udp
2020-03-18T20:34:56.510+0800 [INFO] agent: Stopping server: protocol=HTTP address=127.0.0.1:8500 network=tcp
2020-03-18T20:34:56.510+0800 [INFO] agent: Waiting for endpoints to shut down
2020-03-18T20:34:56.510+0800 [INFO] agent: Endpoints down
2020-03-18T20:34:56.510+0800 [INFO] agent: Exit code: code=0
当你发出leave命令时,consul会通知其他成员该代理离开了数据中心。当代理离开时,它在同一节点上运行的本地服务及其检查将从catalog中删除,consul将不再尝试再次连接访问该节点。
强制终止代理进程,其实是向consul数据中心中的其他代理表明该节点出现了故障,而不是离开。当一个节点发生故障时,它的健康状态被标记为危急状态,但不会从catalog中删除它。consul将自动尝试重新连接到一个发生故障的节点,假设它可能由于网络分区而不可用,并且它可能会返回。
如果代理是作为服务器运行的,适当的退出对于避免造成影响一致性协议的潜在可用性中断是很重要的。有关如何安全地添加和删除服务器的详细信息,请参阅添加和删除服务器指南
三.注册服务和健康检查服务发现
前面我们运行了一个本地consul代理,并检查了数据中心的其他成员。下面我们将通过注册服务和健康检查开始使用consul。
consul的主要用例之一是服务发现。consul提供了一个DNS接口,下游服务可以使用该接口查找其上游依赖项的IP地址。
consul知道这些服务的位置,因为每个服务都向其本地consul客户端注册。操作员可以手动注册服务,配置管理工具可以在部署服务时注册服务,或者容器编制平台可以通过集成自动注册服务。
定义一个服务
你可以通过提供服务定义(这是注册服务的最常见方式)来注册服务,也可以通过调用HTTP API来注册服务。这里我们将使用服务定义。
首先,为consul配置创建一个目录。consul加载配置目录中的所有配置文件,因此Unix系统的一个常见约定是将该目录命名为/etc/ consulc.d (.d后缀表示“此目录包含一组配置文件”)。
$ mkdir ./consul.d
接下来,编写一个服务定义配置文件。假设有一个名为“web”的服务在端口80上运行。使用以下命令创建一个名为web的文件。配置目录中的json。此文件将包含服务定义:名称、端口和一个可选标记,您可以使用该标记在以后查找服务。(在本例中,除了$之外,复制整个代码块以运行命令并创建文件。)
$ echo '{"service":
{"name": "web",
"tags": ["rails"],
"port": 80
}
}' > ./consul.d/web.json
现在,重新启动代理,使用命令行标志来指定配置目录并启用代理上的脚本检查。
在某些配置中启用脚本检查可能会引入远程执行漏洞,这是已知的恶意软件的目标。在生产环境中,我们强烈建议使用-enable-local-script-check。
consul agent -dev -enable-script-checks -config-dir=./consul.d
==> Starting Consul agent...
Version: 'v1.7.2'
Node ID: 'e4768fed-0c53-9644-df15-7029a436e0ec'
Node name: 'alias'
Datacenter: 'dc1' (Segment: '<all>')
Server: true (Bootstrap: false)
Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600)
Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false
==> Log data will now stream in as it occurs:
...
automatically: check=serfHealth
2020-03-18T21:20:07.878+0800 [DEBUG] agent: Node info in sync
2020-03-18T21:20:07.878+0800 [DEBUG] agent: Service in sync: service=web
2020-03-18T21:20:07.878+0800 [DEBUG] agent: Node info in sync
2020-03-18T21:20:07.878+0800 [DEBUG] agent: Service in sync: service=web
2020-03-18T21:20:07.941+0800 [DEBUG] agent.tlsutil: OutgoingRPCWrapper: version=1
再输出中看到到consul“sync”了web服务。这意味着代理从配置文件中加载服务定义,并成功地将其注册到服务目录中。
在一个多代理consul数据中心中,每个服务将向其本地consul客户端注册,客户端将注册转发给维护服务目录的consul服务器。
如果希望注册多个服务,可以在consul配置目录中创建多个服务定义文件。
查询服务
一旦代理将服务添加到consul的服务目录中,你就可以使用DNS接口或HTTP API来查询它。
DNS 接口
首先使用consul的DNS接口查询web服务。在consul处注册的服务的DNS名称是NAME.service.consul
,这里的NAME
是您用来注册服务的名称(在本例中是web)。默认情况下,所有DNS名称都在consul名称空间中,不过这是可配置的。
该web服务的完全限定域名是web.service.consul。查询注册服务的DNS接口(在端口8600上缺省运行的consul)。
$ dig @127.0.0.1 -p 8600 web.service.consul
; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> @127.0.0.1 -p8600 web.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42592
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;web.service.consul. IN A
;; ANSWER SECTION:
web.service.consul. 0 IN A 127.0.0.1
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Wed Mar 18 21:29:38 CST 2020
;; MSG SIZE rcvd: 63
可以看到,返回了一条A记录,其中包含注册服务的IP地址。一条记录只能保存IP地址。
你还可以使用DNS接口以SRV记录的形式检索整个地址/端口对。
$ dig @127.0.0.1 -p 8600 web.service.cosnul SRV
; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> @127.0.0.1 -p 8600 web.service.consul SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36320
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 3
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;web.service.consul. IN SRV
;; ANSWER SECTION:
web.service.consul. 0 IN SRV 1 1 80 alias.node.dc1.consul.
;; ADDITIONAL SECTION:
alias.node.dc1.consul. 0 IN A 127.0.0.1
alias.node.dc1.consul. 0 IN TXT "consul-network-segment="
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Wed Mar 18 21:33:18 CST 2020
;; MSG SIZE rcvd: 140
SRV记录表明,web服务运行在端口80上,并且存在于节点alias.node.dc1.consul。带有该节点的A记录的DNS将返回另一个部分。
最后,还可以使用DNS接口按标记过滤服务。基于标记的服务查询的格式TAG.NAME.service.consul
。在下面的示例中,你将询问带有“rails”标记的所有web服务。你将获得一个成功的响应,因为你使用该标记注册了web服务。
$ dig @127.0.0.1 -p 8600 raild.web.service.consul
; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> @127.0.0.1 -p 8600 rails.web.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27583
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;rails.web.service.consul. IN A
;; ANSWER SECTION:
rails.web.service.consul. 0 IN A 127.0.0.1
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Wed Mar 18 21:36:59 CST 2020
;; MSG SIZE rcvd: 69
HTTP API
除了DNS接口之外,您还可以使用HTTP API查询服务。
$ curl http://localhost:8500/v1/catalog/service/web
[
{
"ID": "e4768fed-0c53-9644-df15-7029a436e0ec",
"Node": "alias",
"Address": "127.0.0.1",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "127.0.0.1",
"lan_ipv4": "127.0.0.1",
"wan": "127.0.0.1",
"wan_ipv4": "127.0.0.1"
},
"NodeMeta": {
"consul-network-segment": ""
},
"ServiceKind": "",
"ServiceID": "web",
"ServiceName": "web",
"ServiceTags": [
"rails"
],
"ServiceAddress": "",
"ServiceWeights": {
"Passing": 1,
"Warning": 1
},
"ServiceMeta": {},
"ServicePort": 80,
"ServiceEnableTagOverride": false,
"ServiceProxy": {
"MeshGateway": {},
"Expose": {}
},
"ServiceConnect": {},
"CreateIndex": 12,
"ModifyIndex": 12
}
]
HTTP API列出了承载给定服务的所有节点。正如你将在稍后讨论服务健康检查时看到的,你通常希望仅过滤健康服务实例的查询,而DNS会在幕后自动执行这些查询。过滤HTTP API查询,只查找健康的实例。
$ curl 'http://localhost:8500/v1/health/service/web?passing'
[
{
"Node": {
"ID": "e4768fed-0c53-9644-df15-7029a436e0ec",
"Node": "alias",
"Address": "127.0.0.1",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "127.0.0.1",
"lan_ipv4": "127.0.0.1",
"wan": "127.0.0.1",
"wan_ipv4": "127.0.0.1"
},
"Meta": {
"consul-network-segment": ""
},
"CreateIndex": 10,
"ModifyIndex": 11
},
"Service": {
"ID": "web",
"Service": "web",
"Tags": [
"rails"
],
"Address": "",
"Meta": null,
"Port": 80,
"Weights": {
"Passing": 1,
"Warning": 1
},
"EnableTagOverride": false,
"Proxy": {
"MeshGateway": {},
"Expose": {}
},
"Connect": {},
"CreateIndex": 12,
"ModifyIndex": 12
},
"Checks": [
{
"Node": "alias",
"CheckID": "serfHealth",
"Name": "Serf Health Status",
"Status": "passing",
"Notes": "",
"Output": "Agent alive and reachable",
"ServiceID": "",
"ServiceName": "",
"ServiceTags": [],
"Type": "",
"Definition": {},
"CreateIndex": 10,
"ModifyIndex": 10
}
]
}
]
更新服务
通过更改服务定义文件,并向代理发送SIGHUP或运行consul reload,可以在不停机的情况下更新服务配置。或者,可以使用HTTP API动态地添加、删除和修改服务。在本例中,将更新注册文件。
首先,通过运行以下命令来编辑注册文件。复制并粘贴整个代码块(不包括$)到你的终端。
$ echo '{"service":
{"name": "web",
"tags": ["rails"],
"port": 80,
"check": {
"args": ["curl", "localhost"],
"interval": "10s"
}
}
}' > ./consul.d/web.json
此服务定义的“check”部分添加了一个基于脚本的健康检查,该检查尝试每10秒通过curl连接到web服务。基于脚本的健康检查与启动consul流程的用户相同。
如果命令使用出口代码>= 2退出,那么检查将失败,consul将认为服务不健康。退出码为1将被视为警告状态。
现在重新加载consul的配置,使其知道新的健康检查。
$ consul reload
Configuration reload triggered
请注意consul日志中的以下几行,它们表明web检查非常重要。
2020-03-18T22:14:05.752+0800 [WARN] agent: Check is now critical: check=service:web
2020-03-18T22:14:05.934+0800 [DEBUG] agent.server: Skipping self join check for node since the cluster is too small: node=alias
2020-03-18T22:14:15.761+0800 [WARN] agent: Check is now critical: check=service:web
2020-03-18T22:14:25.770+0800 [WARN] agent: Check is now critical: check=service:web
consul的DNS服务器只返回健康的结果。再次查询web服务的DNS。它不应该返回任何IP地址,因为web的健康检查失败了。
$ dig @127.0.0.1 -p 8600 web.service.consul
; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> @127.0.0.1 -p 8600 web.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 17056
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;web.service.consul. IN A
;; AUTHORITY SECTION:
consul. 0 IN SOA ns.consul. hostmaster.consul. 1584540983 3600 600 86400 0
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Wed Mar 18 22:16:23 CST 2020
;; MSG SIZE rcvd: 97
响应中没有应答部分,因为consul已经将web服务标记为不健康。