Cluster Singleton

模块信息

要使用Cluster Singleton,必须在项目中添加以下依赖项:

介绍

对于某些用例,确保集群中某个位置恰好有一个特定类型的actor运行非常方便,有时甚至是强制性的。

一些例子:

  • 单一责任点,对某些集群范围内一致的决策或对整个集群系统中的动作进行协调
  • 外部系统的单一入口点
  • 单一master,很多workers
  • 集中命名服务或路由逻辑

使用单例不应该是首选设计。它具有几个缺点,例如单点瓶颈。单点故障也是一个相关问题,但是在某些情况下,此功能通过确保最终启动另一个单例实例来解决此问题。

警告
确保不要使用群集关闭策略,以免在网络出现问题或系统过载(长时间的GC暂停)时将群集拆分为几个单独的群集,因为这将导致启动多个Singleton,每个单独的群集一个!请参阅 Downing

单例manager

集群单例模式管理一个单例actor实例,该actor在所有集群节点或标记有特定角色的一组节点中。单例管理器是一个actor,在集群中的所有节点或所有指定角色的节点上最早使用ClusterSingleton.init的节点启动该actor。

实际的单例actor是:

  • 从最早的节点开始,通过Behavior创建子actor。它可以确保在任何时间点最多运行一个单例实例。
  • 始终在具有指定角色的最早成员上运行。

最早的成员由akka.cluster.Member#isOlderThan确定。从集群中删除成员时,这可能会改变。请注意,在短时间内,切换过程中没有活动的单例。

当最早的节点正在离开群集时,在启动新的单例之前,最早的节点和新的最早的节点进行交换。

群集故障检测器将通知最早的节点何时由于JVM崩溃,强行关闭或网络故障等原因而无法访问。在关闭并删除该节点之后,新的最早的节点将接管并创建新的单例actor。对于这些故障情况,将不会进行顺畅的移交,但是通过所有合理的方法都可以防止一个以上的活动单例。某些极端情况最终会通过可配置的超时来解决。可以通过使用Lease来增加安全性。

单例代理

要与集群中的给定命名单例进行通信,您可以通过代理ActorRef访问它。在ActorRef返回的节点上为给定的singletonName调用ClusterSingleton.init时。通过此ActorRef,您可以将消息发送到单例实例,而与单例实例处于的节点无关。可以多次调用ClusterSingleton.init,如果在此节点上已经有一个单例管理器在运行,则不会启动其他管理器,并且如果有一个正在运行的ActorRef返回代理。

代理会将所有消息路由到单例的当前实例,并跟踪集群中最早的节点并发现单例的ActorRef。可能在一段时间内单例不可用,例如,当节点离开群集时。在这些情况下,代理将缓冲发送到单例的消息,然后在单例最终可用时将其传递。如果缓冲区已满,则通过代理发送新消息时,代理将丢弃旧消息。缓冲区的大小是可配置的,可以通过将缓冲区大小设置为0来禁用它。

值得注意的是,由于这些actors的分散性,消息总是会丢失。与往常一样,应该在单例(确认)和客户端(重试)actors中实现其他逻辑,以确保至少一次传递消息。

单例实例将不会在状态为WeaklyUp的成员上运行。

需要注意的潜在问题

最初使用此模式似乎很诱人,但是它有一些缺点,下面列出了其中的一些缺点:

  • 群集单例可能很快成为性能瓶颈。
  • 您不能依靠集群单例来提供不间断的服务,例如当已运行单例的节点死亡时,将需要几秒钟的时间来发现这一点,并将单例迁移到另一个节点。
  • 如果多个单例注意到所有这些都将在最早的节点(或具有配置角色的最旧的节点)上运行。群集分片与使“单个”实体保持活动结合起来可能是更好的选择。
警告
请确保不要使用“群集关闭”策略,以免在网络出现问题或系统过载(长时间的GC暂停)时将群集拆分为几个单独的集群,因为这将导致启动多个Singleton,每个单独的群集一个单例! 请参阅Downing。

例子

任何行为都可以作为单例运行。 例如。 基本计数器:

然后,在集群中的每个节点上或具有给定角色的每个节点上,使用ClusterSingleton扩展生成单例。 这个实例是群集的数据中心:

监督

当引发异常时,默认的监视策略是使actor停止。 上面的示例将覆盖此方法以重新启动,以确保其始终运行。 另一个选择是重新启动并回退:

请注意,这有时会导致重新启动延迟,导致单例无法运行。 有关监督选项的完整列表,请参见Fault Tolerance

应用程序特定的停止消息

应用程序特定的stopMessage可用于在实际停止单例actor之前关闭资源。 该stopMessage被发送到单例actor,告诉它完成工作,关闭资源并停止。 单例角色终止后,将完成向新的最旧节点的切换。 如果关闭逻辑不包含任何异步操作,则可以在PostStop信号处理程序中执行它。

租约

可以将租约用作额外的安全措施,以确保两个单例不会同时运行。发生这种情况的原因:

  • 网络分区,没有适当的中断提供程序
  • 部署过程中的错误导致了两个单独的Akka集群
  • 从网络分区的一侧群集中删除成员,在另一侧关闭它们,产生的计时问题

租约可以作为最终备份,这意味着除非获得租约,否则不会创建单例actor。

要将租约用于单例,需要在配置中设置akka.cluster.singleton.use-lease。使用名称为-singleton-的租约,并将所有者设置为Cluster.get(system).selfAddress().hostPort()

如果集群单例管理器无法获取租约,则它将作为集群中最早的节点继续尝试。如果租约丢失,则单例actor将被终止,然后将重试获取租约。

访问另一个数据中心的单例

待办事项#27705

配置

使用ActorSystem参数创建时,ClusterSingletonManagerSettings将读取以下配置属性。也可以修改ClusterSingletonManagerSettings或从另一个配置部分使用以下相同的布局创建它。 ClusterSingletonManagerSettings是ClusterSingletonManager.props工厂方法的参数,即每个单例可以根据需要配置不同的设置。

使用ActorSystem参数创建时,ClusterSingletonSettings将读取以下配置属性。 ClusterSingletonSettings是ClusterSingleton.init中的可选参数。 也可以修改ClusterSingletonProxySettings或从另一个配置部分使用以下相同的布局创建它。

你可能感兴趣的:(akka,cluster)