10

我如何使用 Consul 来确保只有一个服务在执行一项任务?

我已经按照http://www.consul.io/中的示例进行操作,但我不能 100% 确定该走哪条路。我应该使用KV吗?我应该使用服务吗?或者我应该使用注册服务作为健康检查并使其可以在给定的时间间隔被集群调用?

例如,假设有几个数据中心。在每个数据中心内,都有许多服务正在运行。这些服务中的每一项都可以发送电子邮件。这些服务必须检查是否有任何电子邮件要发送。如果有,然后发送电子邮件。但是,我不希望多次发送同一封电子邮件。

它如何确保所有电子邮件都已发送,并且没有多次发送?

我可以使用其他技术来做到这一点,但我正在尝试使用 Consul 来实现这一点。

4

2 回答 2

7

这正是Consul 分布式锁的用例

例如,假设您在不同的 AWS 可用区中有三台服务器用于故障转移。每个都启动:

consul lock -verbose lock-name ./run_server.sh

Consul 代理只会运行./run_server.sh服务器首先获得锁的命令。如果./run_server.sh在带有锁的服务器上失败,Consul 代理将释放锁,另一个首先获取它的节点将执行./run_server.sh。这样您就可以进行故障转移,并且一次只能运行一个服务器。如果您正确注册了您的 Consul 健康检查,您将能够看到第一个节点上的服务器出现故障,您可以修复并重新启动该consul lock ...节点上的服务器,它将阻塞直到它可以获取锁。

目前,分布式锁定只能在单个 Consul 数据中心内发生。但是,由于由您决定 Consul 服务器组成数据中心的内容,您应该能够解决您的问题。如果您想锁定跨联邦领事数据中心,您将不得不等待它,因为它是一个路线图项目。

于 2015-06-26T02:32:56.550 回答
3

第一点:问题是如何使用Consul来解决一个具体的问题。然而,Consul 无法解决该特定问题,因为 gossip 协议的本质限制。

当一个数据中心无法与另一个数据中心通信时,您无法安全地确定问题是网络还是受影响的数据中心。

通常的解决方案是定义当一个 DC 无法与另一个 DC 通信时会发生什么。例如,如果我们有 3 个数据中心(DC1、DC2 和 DC3),我们可以确定每当一个 DC 无法与其他 2 个 DC 通信时,它将停止更新数据库。

如果 DC1 无法与 DC2 和 DC3 通信,则 DC1 将停止更新数据库,系统将假定 DC2 和 DC3 仍然在线。

让我们假设 DC2 和 DC3 仍然在线并且它们可以相互通信,那么我们就有了继续运行系统的法定人数。

当 DC1 再次联机时,它将赶上数据库。

领事可以在哪里提供帮助?它可以在 DC 之间进行通信并检查它们是否在线……但 ICMP 也可以。

看看评论。这是否回答你的问题?并不真地。但我认为这个问题没有答案。

第二点:问题是“如何在leader选举中使用Consul?” 最好问问领事是如何选举新领导人的。或者“鉴于 Consul.io 中的文档,您能否举个例子说明如何使用 Consul 确定领导者”。

如果那是您真正想要的,那么问题已经得到解答:Consul 代理如何知道它是集群的领导者?

于 2015-01-08T08:23:27.053 回答