介绍Akka-Cluster
前 需要先说一下Akka-Remoting
.
Akka-Remoting
一种ActorSystem之间Actor对Actor点对点的沟通协议.通过Akka-Remoting来实现一个ActorSystem中的一个Actor与另一个ActorSystem中的另一个Actor之间的沟通.在Remoting功能之后,Akka又发展了集群Cluster功能.Akka-Cluster
是基于Akka-Remoting之上的新一代分布式运算环境,所以Remoting已经成为了Akka-Cluster的内部支持功能,在生产环境中的分布式运算应该尽量使用Akka-Cluster; Akka-Cluster可以在一部物理机或一组网络连接的服务器上搭建部署.
简单来说Akka-Cluster将多个JVM连接整合起来,实现消息地址的透明化和统一化使用管理,集成一体化的消息驱动系统.最终目的是能够把一个大型程序分割成多个子程序,然后部署到很多JVM上去实现程序的分布式并行运算.更重要的是:Cluster的构建过程与Actor编程没有牵连,当Cluster把多个ActorSystem集合成一个统一系统后,我们可以用在单一ActorSystem里编程的习惯方式编写分布式运算程序.由于在单一机器上就可以配置多个节点形成一个集群,我们开发的分布式程序可以在单机或多机群上运行,不同的只是如何部署和配置集群环境.
工程结构
1 | [root@localhost akka-task ]$ tree akka-task |
Maven依赖
1 | <dependency> |
模块说明
消息相关
- Message: 示例中客户端和服务端通讯的消息定义
服务端相关
- TaskActor: 服务端事件处理类
- TaskClusterServer* : 服务端实例主类(示例中定义了3台实例)
- akka-node*.conf : 服务端配置
客户端相关
- DispatchActor: 消息投递转发类, 用于对于服务端节点进行选取和消息投递
- TaskClusterClient: 客户端示例主类
- akka-client.conf : 客户端配置
代码示例(服务端)
示例中定义的服务端端端口分别为:2551、2552、2553
消息定义
说明: 消息定义必须实现序列化接口
1 | public class Message implements Serializable{ |
服务端配置
akka-node1.conf
配置内容
1 | akka { |
akka-node2.conf
配置内容
1 | akka { |
akka-node3.conf
配置内容
1 | akka { |
服务端Actor
1 | public class TaskActor extends AbstractLoggingActor { |
服务端主类
这里只列出Node1上的主类, 服务端节点中每个示例的内容基本一样,不同的是各自加载的配置文件"akka-node*.conf"
与实例对应.
1 | public class TaskClusterServer1 { |
集群状态监听
示例场景: 分别启动服务端节点Node1、Node2、Node3、然后关停Node2、再重新启动,观察集群状态日志
Node1日志
1 | [INFO] [01/31/2018 11:45:06.365] [main] [akka.remote.Remoting] Starting remoting |
Node2日志
首次加入集群
1 | [INFO] [01/31/2018 11:45:12.982] [main] [akka.remote.Remoting] Starting remoting |
断开后再次加入集群
1 | [INFO] [01/31/2018 11:46:56.861] [main] [akka.remote.Remoting] Starting remoting |
Node3日志
1 | [INFO] [01/31/2018 11:45:17.020] [main] [akka.remote.Remoting] Starting remoting |
通过日志示例和服务端代码可以看到集群事件是通过MemberEvent传递的,这个其实就是每个成员所可能拥有的events,一个成员在它的生命周期中有以下的events:
- ClusterEvent.MemberJoined - 新的节点加入集群,此时的状态是Joining;
- ClusterEvent.MemberUp - 新的节点加入集群,此时的状态是Up;
- ClusterEvent.MemberExited - 节点正在离开集群,此时的状态是Exiting;
- ClusterEvent.MemberRemoved - 节点已经离开集群,此时的状态是Removed;
- ClusterEvent.UnreachableMember - 节点被标记为不可触达;
- ClusterEvent.ReachableMember - 节点被标记为可触达;
状态说明:
- Joining: 加入集群的瞬间状态
- Up: 正常服务状态
- Leaving / Exiting: 正常移出中状态
- Down: 被标记为停机(不再是集群决策的一部分)
- Removed: 已从集群中移除
代码示例(客户端)
示例中定义的客户端端口为:2600
客户端配置
1 | akka { |
客户端消息转发
1 | public class DispatchActor extends AbstractLoggingActor { |
客户端主类
1 | public class TaskClusterClient { |
客户端分别演示了指定节点处理和基于集群处理.
分布式计算
启动服务端: 分别启动服务端节点(Node1、Node2、Node3)、
启动客户端: 启动客户端主类模拟调用
服务端日志
Node1日志
1 | [INFO] [01/31/2018 12:09:28.361] [main] [akka.remote.Remoting] Starting remoting |
Node2日志
1 | [INFO] [01/31/2018 12:09:38.816] [main] [akka.remote.Remoting] Starting remoting |
Node3日志
1 | [INFO] [01/31/2018 12:09:48.069] [main] [akka.remote.Remoting] Starting remoting |
客户端日志
1 | [INFO] [01/31/2018 12:10:21.847] [main] [akka.remote.Remoting] Starting remoting |