我正在构建一个使用 consul 进行服务发现的云堆栈,但是遇到了障碍,因此我向互联网人士询问了这个问题。
我想要做的是从多个主机在 consul 中注册一个服务,但在服务启动时,对于所有查询仅返回其中一个。确切地说:
- 节点 A、节点 B、节点 C 均能够提供服务 X
- 所有节点均已启动并运行
- 他们都将服务注册到领事馆。
此时,当我向 consul 查询这些数据时,我将获得所有三个节点的答案。我确实只想获取其中一个节点,只要该节点提供服务,但如果没有,我想获取另一个节点来处理所有问题。
更确切地说,举个例子:我建立了一个 xtradb 集群,其中一个节点必须从我们的旧数据中心进行复制。在给定时刻可能只有一个节点在进行复制,但如果该节点发生故障,其他一些节点必须继续复制。
我可以使用外部监控主机来解决这个问题,但这可能是 SPOF,因此最好的方法是在所有节点上放置一个复制监控脚本,该脚本会向 consul 询问“我是否是负责复制的主机?”如果答案是肯定的,则在本地设置副本。理论上,如果该节点发生故障,consul 可以投票选出新的“副本主节点”——并且该节点上的代理将设置复制。
那么,consul 能做到这一点吗?如果不行,还有其他方法可以实现吗?(我们在 GCP 上运行,因此我无法使用磁盘或浮动 IP 进行仲裁。所有主机都是独立的,我需要一些可以对主机达成共识的层。)在最坏的情况下,我会自己写这个,但最好有一个可用于生产的解决方案。
答案1
假设您有 3 个服务正在运行并在 consul 上注册,并且查询
curl -s 'http://localhost:8500/v1/catalog/service/consul' | jq ''
结果如下
[{
"Node": "local01-consul0001.local",
"Address": "192.168.33.11",
"ServiceID": "consul",
"ServiceName": "consul",
"ServiceTags": [
"master"
],
"ServiceAddress": "",
"ServicePort": 8300
},
{
"Node": "local01-consul0002.local",
"Address": "192.168.33.12",
"ServiceID": "consul",
"ServiceName": "consul",
"ServiceTags": [
"master"
],
"ServiceAddress": "",
"ServicePort": 8300
},
{
"Node": "local01-consul0003.local",
"Address": "192.168.33.13",
"ServiceID": "consul",
"ServiceName": "consul",
"ServiceTags": [
"master"
],
"ServiceAddress": "",
"ServicePort": 8300
}]
由于所有内容都可用,您应该能够按字母数字顺序使用第一个:
# curl -s 'http://localhost:8500/v1/catalog/service/consul' | jq '.[0]'
{
"Node": "local01-consul0001.local",
"Address": "192.168.33.11",
"ServiceID": "consul",
"ServiceName": "consul",
"ServiceTags": [
"master"
],
"ServiceAddress": "",
"ServicePort": 8300
}