使用Consul的领导选举

2023/05/13

1. 概述

在本教程中,我们将了解Consul领导选举如何帮助确保数据稳定性。我们将提供一个实际示例,说明如何在并发应用程序中管理分布式锁定。

2. 什么是Consul?

Consul是一个开源工具,提供基于健康检查的服务注册和发现。此外,它还包括一个Web图形用户界面(GUI),用于查看Consul并轻松与之交互。它还涵盖会话管理和键值(KV)存储的额外功能。

在接下来的部分中,我们将重点介绍如何使用Consul的会话管理和KV存储来选择具有多个实例的应用程序中的领导者

3. Consul基础

Consul代理是运行在Consul集群的每个节点上的最重要的组件。它负责健康检查;注册、发现和解析服务;存储配置数据、等等。

Consul代理可以以两种不同的模式运行-服务器和代理。

Consul服务器的主要职责是响应来自代理的查询并选举领导者。使用共识协议选择领导以提供基于Raft算法一致性(由CAP定义)

详细讨论共识的工作原理不在本文的讨论范围内。不过,值得一提的是,节点可以处于三种状态之一:领导者、候选者或追随者。它还存储数据并响应来自代理的查询。

代理比Consul服务器更轻量级。它负责运行已注册服务的健康检查并将查询转发到服务器。让我们看一个Consul集群的简单图表:

Consul还可以在其他方面提供帮助-例如,在一个实例必须是领导者的并发应用程序中

在接下来的部分中,让我们看看Consul如何通过会话管理和KV存储来提供这一重要功能。

4. Consul领导选举

在分布式部署中,持有锁的服务是领导者。因此,对于高可用系统,管理锁和领导者是至关重要的。

Consul提供了一个易于使用的KV存储和会话管理。这些功能用于建立领导者选举,所以让我们了解它们背后的原理。

4.1 领导之争

属于分布式系统的所有实例所做的第一件事就是争夺领导权。成为领导者的竞争包括一系列步骤:

  1. 所有实例必须就一个共同密钥达成一致才能进行竞争。
  2. 接下来,实例通过Consul会话管理和KV功能使用约定的密钥创建会话。
  3. 第三,他们应该获得会话。如果返回值为true,则锁属于该实例,如果为false,则该实例是追随者。
  4. 实例需要持续监视会话以在失败或释放时再次获得领导权
  5. 最后,领导者可以释放会话,然后重新开始这个过程。

一旦领导者被选出,其余实例使用Consul KV和会话管理通过以下方式发现领导者:

  • 检索约定的密钥
  • 获取会话信息以了解领导者

4.2 一个实际例子

我们需要在运行多个实例的Consul中创建键和值以及会话。为此,我们将使用Kinguin Digital Limited Leadership Consul开源Java实现。

首先,让我们包含依赖项:

<dependency>
    <groupId>com.github.kinguinltdhk</groupId>
    <artifactId>leadership-consul</artifactId>
    <version>${kinguinltdhk.version}</version>
    <exclusions>
        <exclusion>
            <groupId>com.ecwid.consul</groupId>
            <artifactId>consul-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

我们排除了consul-api依赖项以避免在Java中的不同版本上发生冲突。

对于公共密钥,我们将使用:

services/%s/leader

让我们用一个简单的片段来测试所有的过程:

new SimpleConsulClusterFactory()
    .mode(SimpleConsulClusterFactory.MODE_MULTI)
    .debug(true)
    .build()
    .asObservable()
    .subscribe(i -> System.out.println(i));

然后我们使用asObservable()创建一个包含多个实例的集群,以方便订阅者访问事件。领导者在Consul中创建会话,所有实例验证会话以确认领导。

最后我们自定义consul的配置和session管理,以及实例间约定的key来选举领导者(leader):

cluster:
    leader:
        serviceName: cluster
        serviceId: node-1
        consul:
            host: localhost
            port: 8500
            discovery:
                enabled: false
        session:
            ttl: 15
            refresh: 7
        election:
            envelopeTemplate: services/%s/leader

4.3 如何测试

有几种安装Consul和运行代理的选项。

部署Consul的一种可能性是通过容器。我们将使用世界上最大的容器镜像仓库Docker Hub中提供的Consul Docker镜像

我们将通过运行以下命令使用Docker部署Consul:

docker run -d --name consul -p 8500:8500 -e CONSUL_BIND_INTERFACE=eth0 consul

Consul现在正在运行,它应该在localhost:8500上可用。

让我们执行代码片段并检查完成的步骤:

  1. 领导者在Consul中创建一个会话
  2. 然后它被选举(elected.first)
  3. 其余实例一直观察直到会话被释放
INFO: multi mode active
INFO: Session created e11b6ace-9dc7-4e51-b673-033f8134a7d4
INFO: Session refresh scheduled on 7 seconds frequency 
INFO: Vote frequency setup on 10 seconds frequency 
ElectionMessage(status=elected, vote=Vote{sessionId='e11b6ace-9dc7-4e51-b673-033f8134a7d4', serviceName='cluster-app', serviceId='node-1'}, error=null)
ElectionMessage(status=elected.first, vote=Vote{sessionId='e11b6ace-9dc7-4e51-b673-033f8134a7d4', serviceName='cluster-app', serviceId='node-1'}, error=null)
ElectionMessage(status=elected, vote=Vote{sessionId='e11b6ace-9dc7-4e51-b673-033f8134a7d4', serviceName='cluster-app', serviceId='node-1'}, error=null)

Consul还提供了一个Web GUI,网址为http://localhost:8500/ui。

让我们打开浏览器并单击Key-Value部分以确认会话已创建:

因此,其中一个并发实例使用为应用程序商定的密钥创建了一个会话。只有当会话被释放时,进程才能重新开始,新的实例才能成为领导者。

5. 总结

在本文中,我们展示了具有多个实例的高性能应用程序中的领导选举基础知识。我们演示了Consul的会话管理和KV存储功能如何帮助获取锁和选择领导者。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章