本文是Akka系列文章,主要以搭建示例为主,后续文章会细聊细节,我想的是先跑起来,然后对已经能跑起来的程序,一点一点剖析,所以你不要纠结哪段代码具体是什么原理,这都是后话
本文将简单的搭建一个akka集群,这个集群有3个节点,分别是service1,service2,service3,并且按照如下步骤进行演示:
- 首先启动service1,然后启动service2
- 此时service1控制台会打印service2注册到集群,service2本身也会打印出自己已经注册到集群
- 启动service3
- 此时service1和service2会打印出service3注册到集群
- 关闭service3
- 此时service1和service2会打印出service3与集群断开连接
- 关闭service2
- 此时service1会打印出service2与集群断开连接
步骤1: 创建3个maven项目,POM文件内容如下
cpp
<dependency>
<!-- 这是akka的基础组件依赖 -->
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.11</artifactId>
<version>2.4.20</version>
</dependency>
<dependency>
<!-- 这是akka的远程调用依赖 -->
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-remote_2.11</artifactId>
<version>2.4.20</version>
</dependency>
<dependency>
<!-- 这是akka的集群配置依赖 -->
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-cluster_2.11</artifactId>
<version>2.4.7</version>
</dependency>
步骤2: 在resources文件夹下创建一个叫做application.conf
的配置文件,akka会自动找这个名字的文件,文件内容如下
service1的配置文件
cpp
akka{
loglevel=off
actor{
provider="akka.cluster.ClusterActorRefProvider"
}
# 自己的IP端口
remote{
log-remote-lifecycle-events=off
enabled-transports=["akka.remote.netty.tcp"]
netty.tcp{
hostname="127.0.0.1"
port=2551
}
}
# 集群初始成员有哪些
cluster{
seed-nodes=[
"akka.tcp://sys@127.0.0.1:2551",
"akka.tcp://sys@127.0.0.1:2552",
"akka.tcp://sys@127.0.0.1:2553"
]
}
}
service2的配置文件
cpp
为了节省篇幅,2的配置文件和1完全相同,但是端口号需要改一下
# ....省略
port=2552
# ....省略
service3的配置文件
cpp
为了节省篇幅,3的配置文件和1完全相同,但是端口号需要改一下
# ....省略
port=2553
# ....省略
步骤3: 创建一个Actor,然后将这个Actor复制3份放到3个项目中,注意:全限定名(也就是包路径)在三个项目中要相同
cpp
package akka.demo.actor;// 注意这里,在service1,2,3中,包名要完全相同,不相同怎么序列化,对不?
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.cluster.Cluster;
import akka.cluster.ClusterEvent;
import akka.cluster.ClusterEvent.MemberJoined;
import akka.cluster.ClusterEvent.UnreachableMember;
public class MyActor extends UntypedActor {
Cluster cluster = Cluster.get(getContext().system());
@Override
public void preStart() throws Exception {
cluster.subscribe(getSelf(), ClusterEvent.MemberJoined.class);
cluster.subscribe(getSelf(), ClusterEvent.UnreachableMember.class);
}
@Override
public void onReceive(Object o) throws Throwable {
if (o instanceof MemberJoined) {
System.out.println("有节点注册到集群了,节点地址是:" + ((MemberJoined) o).member().address());
}
if(o instanceof UnreachableMember){
System.out.println("有节点从集群断开了,节点地址是:" + ((UnreachableMember) o).member().address());
}
// 进入else说明是其他类型的消息,与本文内容无关,所以无需关心,后续其他文章会讲,本章暂不考虑
else {
System.out.println("其他消息:" + o);
}
}
public static void main(String[] args) throws Throwable {
ActorSystem system = ActorSystem.create("sys");
// 创建一个叫做abc的Actor,由于我们指定了MyActor.class,所以这个abc会订阅【节点加入】
// 和【节点异常断开】事件
ActorRef routeActorRef = system.actorOf(Props.create(MyActor.class), "abc");
}
}
步骤4: 按照本文开头的8步,依次进行操作即可
- 首先启动service1,然后启动service2
- 此时service1控制台会打印service2注册到集群,service2本身也会打印出自己已经注册到集群
- 启动service3
- 此时service1和service2会打印出service3注册到集群
- 关闭service3
- 此时service1和service2会打印出service3与集群断开连接
- 关闭service2
- 此时service1会打印出service2与集群断开连接
本文到这里就结束了,本系列文章到此,可以说是单机到集群的几个例子都跑通了,后续的文章将会详细介绍Akka的各个细节
上一篇文章:Akka-路由模式Group/Pool
下一篇文章:[Akka-HTTP框架](没开始写 TODO)