多群集通信

网络必须通过某种方式进行配置,以便任何 Orleans 接收器都可以通过 TCP/IP 连接到任何其他 Orleans 接收器,而不管它位于何处。 具体来说,实现此目标的方法超出了 Orleans 的范围,因为它取决于部署接收器的方式和位置。

例如,在 Windows Azure 上,我们可以使用 VNet 连接区域中的多个部署,并使用网关跨不同区域连接 VNet。

群集标识符

每个群集都有自己的唯一群集 ID。群集 ID 必须在全局配置中指定。

群集 ID 不能为空,也不能包含逗号。 此外,如果使用 Azure 表存储,群集 ID 可能不包含行键禁止的字符 (/, , #, ?)。

我们建议群集 ID 使用非常短的字符串,因为群集 ID 经常传输,并且可能会由某些日志视图提供程序存储在存储中。

群集网关

每个群集都会自动指定一部分活动接收器来充当群集网关。 群集网关直接将其 IP 地址播发到其他群集,因此可以充当“第一个接触点”。 默认情况下,最多 10 个接收器(或任意数量配置为 MaxMultiClusterGateways)指定为群集网关。

不同群集中的接收器之间的通信并不总是通过网关传递。 一旦接收器了解并缓存粒度激活的位置(无论在哪个群集中),就会直接将消息发送到该接收器,即使接收器不是群集网关也是如此。

Gossip

Gossip 是群集共享配置和状态信息的机制。 顾名思义,Gossip 是分散和双向的:每个接收器直接与同一个群集和其他群集中的其他接收器通信,以在两个方向交换信息。

Content。 Gossip 包含以下部分或全部信息:

  • 带有当前时间戳的多群集配置
  • 包含有关群集网关的信息的字典。 键是接收器地址,值包含 (1) 时间戳,(2) 群集 ID,(3) 状态,状态为活动或非活动。

快传播和慢传播。 当网关更改其状态或操作员注入新配置时,此 Gossip 信息将立即发送到所有接收器、群集和八卦频道。 这种情况会很快发生,但并不可靠。 如果由于任何原因(例如争用、套接字中断、接收器故障)而丢失消息,我们的定期后台 Gossip 可确保信息最终传播,尽管速度较慢。 所有信息最终传播到任何位置,并且在偶尔的消息丢失和故障方面具有高度弹性。

所有 Gossip 数据都带有时间戳,这可确保较新的信息替换较旧的信息,而不管消息的相对计时如何。 例如,较新的多群集配置替换较旧的多群集配置,而有关网关的较新信息替换有关该网关的较旧信息。 有关 Gossip 数据的表示形式的详细信息,请参阅 MultiClusterData 类。 它具有组合 Gossip 数据的 Merge 方法,可使用时间戳解决冲突。

Gossip 频道

首次启动接收器或发生故障后重新启动时,需要有一种方法来启动 Gossip。 这是 Gossip 频道的角色,可在接收器配置中配置。 启动时,接收器从 Gossip 频道中提取所有信息。 启动后,接收器定期发出 Gossip 信息,频率为每 30 秒或配置为 BackgroundGossipInterval。 每次将 Gossip 信息与从所有群集网关和 Gossip 频道中随机选择的合作伙伴同步。

  • 虽然并不严格要求,但我们建议始终在不同的区域中至少配置两个 Gossip 频道,以提高可用性。
  • 与 Gossip 频道通信的延迟并不重要。
  • 只要 ServiceId Guid(由各自的配置指定)不同,多个不同的服务就可以不受干扰地使用同一个 Gossip 频道。
  • 没有任何严格的要求,即只要频道足以让接收器在启动时最初与“Gossip 社区”连接,所有接收器就可以使用同一个 Gossip 频道。 但是,如果 Gossip 频道不属于接收器的配置,而该接收器是网关,则不会将其状态更新推送到该频道(快传播),因此在通过定期后台 Gossip 到达该频道之前可能需要更长的时间(慢传播)。

基于 Azure 表的 Gossip 频道

我们已基于 Azure 表实现了 Gossip 频道。 配置指定用于 Azure 帐户的标准连接字符串。 例如,配置可以使用单独的 Azure 存储帐户 usaeurope 指定两个 Gossip 频道,如下所示:

var silo = new HostBuilder()
    .UseOrleans(builder =>
    {
        builder.Configure<MultiClusterOptions>(options =>
        {
            options.GossipChannels.Add(
                "AzureTable",
                "DefaultEndpointsProtocol=https;AccountName=usa;AccountKey=...");
            options.GossipChannels.Add(
                "AzureTable",
                "DefaultEndpointsProtocol=https;AccountName=europe;AccountKey=...")
        });
    })

只要 ServiceId Guid(由各自的配置指定)不同,多个不同的服务就可以不受干扰地使用同一个 Gossip 频道。