使用 Consul 作为成员管理器

Consul 是一种分布式、高度可用的数据中心感知服务发现平台,包括简单的服务注册、运行状况检查、故障检测和密钥值存储。 它基于这样的前提:数据中心中的每个节点都运行着一个 Consul 代理,该代理可以充当服务器或客户端。 每个代理通过可缩放的 gossip 协议进行通信。

Consul 的概述非常详细,包括此处的类似解决方案比较。

Consul 以 Go 编写,开源;编译的下载可用于 macOS X、FreeBSD、Linux、Solaris 和 Windows

为什么选择 Consul?

作为 Orleans 成员资格提供商,当你需要提供不需要潜在客户拥有现有基础结构和合作 IT 提供商的本地解决方案时,Consul 是一个不错的选择。 Consul 是一个轻型单一可执行文件,没有依赖项,因此可以轻松内置到中间件解决方案中。 当 Consul 是您用于发现、检查和维护微服务的解决方案时,与 Orleans 会员进行完全集成对于简单操作和易用性是有意义的。 Consul 中也存在成员身份表(也称为“Orleans 自定义系统存储”),它与 Orleans的 群集管理完全集成。

安装 Consul

Consul.io 上提供了关于如何设置稳定 Consul 集群的详细文档,这里没有必要重复这些内容。 但是,为了方便起见,我们提供了本指南,从而可以快速让 Orleans 与独立的 Consul 代理一起运行。

  1. 创建将 Consul 安装到的文件夹(例如 C:\Consul)。

  2. 创建子文件夹:C:\Consul\Data(如果不存在,Consul 不会创建此目录)。

  3. 下载 并将 Consul.exe 解压缩到 C:\Consul

  4. C:\Consul 打开命令提示符,并运行以下命令:

    ./consul.exe agent -server -bootstrap -data-dir "C:\Consul\Data" -client='0.0.0.0'
    

    在前面的命令中:

    • agent:指示 Consul 运行承载服务的代理进程。 如果没有此开关,Consul 进程会尝试使用 RPC 配置正在运行的代理。
    • -server:将代理定义为服务器而不是客户端(Consul 客户端 是托管所有服务和数据的代理,但没有投票权来决定群集领导者,并且不能成为群集领导者。
    • -bootstrap:必须引导群集中的第一个节点(并且仅引导第一个节点!),以便假设群集领导关系。
    • -data-dir [path]:指定存储所有 Consul 数据的路径,包括群集成员身份表。
    • -client='0.0.0.0':通知 Consul 在哪个 IP 地址上启动服务。

    还有其他许多参数,以及使用 JSON 配置文件的选项。 有关选项的完整列表,请参阅 Consul 文档。

  5. 通过 http://localhost:8500/v1/catalog/services在浏览器中打开服务终结点,验证 Consul 是否正在运行并准备好接受来自 Orleans 的成员身份请求。 正常运行时,浏览器会显示以下 JSON:

    {
        "consul": []
    }
    

配置 Orleans

若要配置 Orleans 以将 Consul 用作成员资格提供程序,接收器项目需要引用 Microsoft.Orleans.Clustering.Consul NuGet 包。 完成此操作后,可以在接收器的 Program.cs 文件中配置成员资格提供程序,如下所示:

IHostBuilder builder = Host.CreateDefaultBuilder(args)
    .UseOrleans(silo =>
    {
        silo.UseConsulSiloClustering(options =>
        {
            // The address of the Consul server
            var address = new Uri("http://localhost:8500");
            options.ConfigureConsulClient(address);
        });
    })
    .UseConsoleLifetime();

using IHost host = builder.Build();
host.Run();

前面的代码:

若要配置客户端,请引用相同的 NuGet 包并调用 UseConsulClientClustering 扩展方法。

客户端 SDK

如果你对使用 Consul 进行服务发现感兴趣,则大多数常用语言都有客户端 SDK

实现细节

成员资格表提供程序通过 Check-And-Set (CAS) 操作使用 Consul 的键/值存储功能。 每个 Silo 启动时,会注册两个键值条目:一个包含 Silo 详细信息,另一个包含上次 Silo 报告它处于活动状态的时间。 后者指的是诊断“我处于活动状态”条目,而不是故障检测的检测信号,这些条目直接在接收器之间发送,并且不会写入表中。 所有对表的写操作都使用 CAS 进行,以提供并发控制,这是由 Orleans的 集群管理协议所要求的。

启动 Silo 后,可以在网络浏览器中查看这些条目,在 http://localhost:8500/v1/kv/?keys&pretty上显示的内容如下所示:

[
    "orleans/default/192.168.1.11:11111@43165319",
    "orleans/default/192.168.1.11:11111@43165319/iamalive",
    "orleans/default/version"
]

所有密钥都以 orleans为前缀,这是在提供程序中硬编码的,旨在避免与 Consul 的其他用户发生密钥空间冲突。 你可以使用这些密钥中的任何一个来检索其他信息。可以通过将密钥名称(不带引号)追加到 http://localhost:8500/v1/kv/ 中的 Consul KV 根目录来读取其中每个密钥。 这样做会向你呈现以下 JSON:

[
    {
        "LockIndex": 0,
        "Key": "orleans/default/192.168.1.11:11111@43165319",
        "Flags": 0,
        "Value": "[BASE64 UTF8 Encoded String]",
        "CreateIndex": 321,
        "ModifyIndex": 322
    }
]

将 Base64 UTF-8 编码的字符串 Value 解码后,您将获得实际的 Orleans 成员数据。

http://localhost:8500/v1/KV/orleans/default/[SiloAddress]

{
    "Hostname": "[YOUR_MACHINE_NAME]",
    "ProxyPort": 30000,
    "StartTime": "2023-05-15T14:22:00.004977Z",
    "Status": 3,
    "SiloName": "Silo_fcad0",
    "SuspectingSilos": []
}

http://localhost:8500/v1/KV/orleans/default/[SiloAddress]/IAmAlive

"2023-05-15T14:27:01.1832828Z"

客户端连接时,使用 URI http://192.168.1.26:8500/v1/KV/orleans/default/?recurse 读取一个 HTTP GET 中群集的所有接收器的 KV。

局限性

使用 Consul 作为成员资格提供程序时,需要注意一些限制。

Orleans 扩展了成员资格协议(表版本和 ETag)

Consul KV 目前不支持原子更新。 因此,Orleans Consul Membership Provider 仅实现 Orleans 基本成员身份协议,如 Orleans群集管理中所述,不支持扩展成员身份协议。 此扩展协议作为附加但不重要的接收器连接验证,并且作为尚未实现的功能的基础引入。

多个数据中心

Consul 中的键值对当前不会在 Consul 数据中心之间复制。 有 单独的项目 来处理这项复制工作,但尚未被证明能够支持 Orleans。

在 Windows 上运行时

Consul 在 Windows 上启动时,它会记录以下消息:

==> WARNING: Windows is not recommended as a Consul server. Do not use in production.

显示此警告消息的原因是在 Windows 环境中运行时缺乏对测试的关注,而不是因为存在任何实际已知问题。 在决定 Consul 是否适合你之前,请阅读 讨论

潜在的未来增强功能

  1. 证明 Consul KV 复制项目可以在多个 Consul 数据中心之间的 WAN 环境中支持 Orleans 群集。
  2. 在 Consul 中实现提醒表。
  3. 实现扩展成员身份协议。 Consul 背后的团队计划实现原子操作,一旦此功能可用,就有可能消除提供程序的限制。