使用Akka Cluster Singleton实现集群单例

上篇文章主要讲了如何使用Akka作异步任务处理。最后还抛出一个问题。

具体问题的描述就不在这篇文章赘述了,我们仅简单回顾一下第一种解决方案:覆写persistenceId()时,加一个UUID,这样三台服务器上的Actor就不会再共享journal。虽然这个方案已经可以解决问题了,但并不是最理想的。首先,现在的项目中只是用akka处理一些无状态的任务异步处理,但是将来肯定要用akka作更多的事情。比如,缓存,DAO这些可以设计成有状态的,而现在actor重启时是不能replay消息消息历史的,所以这样不能最大限度发挥actor的优势。还有,我的目标是把所有的后端server构建为一个逻辑上的server,现在他们仍然是三个各自为营的独立server。因此我又继续作了一些调研,最终发现了Cluster Singleton。

文档上给出了Cluster Singleton的适用场景:

  • 集群中的单点决策,或者协调
  • 统一外部系统出口
  • 一主多从
  • 统一命名服务或路由逻辑

第二点正好就是我们的场景。下边看一下如何使用Cluster Singleton。

  1. 添加依赖(我用的构建工具是Gradle)
compile("com.typesafe.akka:akka-cluster_2.11:${akkaVersion}")
compile("com.typesafe.akka:akka-cluster-tools_2.11:${akkaVersion}")
  1. 创建actor
actorSystem.actorOf(ClusterSingletonManager.props(
    SpringExtProvider.get(actorSystem).props("NotificationActor"),
    PoisonPill.getInstance(),
    ClusterSingletonManagerSettings.create(actorSystem).withRole("master")
), "notification-master");

notificationActor = actorSystem.actorOf(
    ClusterSingletonProxy.props(
        "/user/notification-master",
        ClusterSingletonProxySettings.create(actorSystem).withRole("master")),
    "notification-proxy");

创建actor比原来复杂了。首先要创建一个ClusterSingletomManager。ClusterSingletonManager也是一个Actor,它会在Cluster的每个节点上都启动起来(或者集群拥有某些角色的节点)。ClusterSingletomManager.props要传入三个参数,第一个是需要创建Singleton实例的Actor配置;第二个是当Manager关闭时要给它管理的Actor发送什么消息;第三个,集群部署配置,即指定ClusterSingletomManager在哪些集群Node上启动。

接下来ClusterSingletonManager会选择一个最老的实例并在上面创建Actor单例。ClusterSingletonManager可以确保整个集群中至多有一个singleton的实例,言下之意,存在没有singleton实例的时刻。比如cluster node crash,原有的singleton实例丢失,这时需要重新选举新最老的ClusterSingletonManager,然后创建新的singleton实例。

访问Singleton Actor需要借助于ClusterSingletonProxy,ClusterSingletonProxy会把所有的消息forward给当前被代理的Actor实例。因为有可能某些时刻是没有singleton actor实例的,所以遇到这种情况ClusterSingletonProxy会先把消息缓存,当新的Actor单例创建之后,再把缓存的消息转发过去。

当然,Cluster Singleton也有它的问题,比如单点潜在的性能问题,而且singleton actor并不是100%可用。但相比于第一种方案,显然这个要更接近我的期望。


write on 2017-1-10

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,252评论 19 139
  • Actor系统的实体 在Actor系统中,actor之间具有树形的监管结构,并且actor可以跨多个网络节点进行透...
    JasonDing阅读 3,423评论 2 6
  • 1 场景问题# 1.1 读取配置文件的内容## 考虑这样一个应用,读取配置文件的内容。 很多应用项目,都有与应用相...
    七寸知架构阅读 6,905评论 12 68
  • 本文档翻译自 http://redis.io/topics/cluster-tutorial 。 本文档是 Red...
    会跳舞的机器人阅读 67,011评论 2 21
  • 这个夏天,我毕业了。 领毕业证的那天下了很大很大的雨,站在校门口的长亭里,看着来来去去的人群,突然间仿佛看到昨天进...
    柠檬小新dy阅读 195评论 1 0