参考链接:http://sunxiang0918.cn/2016/01/13/Akka-in-JAVA-2/#Router
参考链接:http://blog.youkuaiyun.com/liubenlong007/article/details/54574064
通常在分布式任务调度系统中会有这样的需求:一组actor提供相同的服务,我们在调用任务的时候只需要选择其中一个actor进行处理即可。
其实这就是一个负载均衡或者说路由策略,akka作为一个高性能支持并发的actor模型,可以用来作为任务调度集群使用,当然负载均衡就是其本职工作了,akka提供了Router
来进行消息的调度。
在真实的情况中,通常针对某一种消息,会启动很多个相同的Actor来进行处理.当然,你可以在程序中循环的启动很多个相同的Actor来实现,就如上一小结中启动100个Actor那样,但是这就牵涉到Actor任务的平衡,Actor个数的维护等等,比较的麻烦.因此,在AKKA中存在一种特殊的Actor,即Router
.Akka通过Router
机制,来有效的分配消息给actor来完成工作.而在AKKA中,被Router
管理的actor被称作Routee
.
根据项目的需求,可以使用不同的路由策略来分发一个消息到actor中.Akka附带了几个常用的路由策略,配置起就可以使用.当然,也可以自定义一个路由器.
InboxActor2
package com.eastcom.first.spark.data.akka.router;
import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;
public class InboxActor2 extends UntypedActor {
private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);
@Override
public void onReceive(Object o) throws Throwable {
if (o == MsgEnum.WORKING) {
log.info("i am working.");
} else if (o == MsgEnum.DONE) {
log.info("i am done");
} else if (o == MsgEnum.CLOSE) {
log.info("i am close." + getContext().self().path());
getContext().stop(getSelf());// 关闭自己
} else {
unhandled(o);
}
}
}
InboxMain2
package com.eastcom.first.spark.data.akka.router;
import java.util.concurrent.atomic.AtomicBoolean;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.routing.RoundRobinPool;
public class InboxMain2 {
public static AtomicBoolean flag = new AtomicBoolean(true);
public static void main(String[] args) throws InterruptedException {
// ActorSystem system = ActorSystem.create("routerTest",
// ConfigFactory.load("akka.config"));
ActorSystem system = ActorSystem.create("System");
ActorRef workerRouter = system.actorOf(Props.create(InboxActor2.class).withRouter(new RoundRobinPool(3)),
"RouterTest");
int i = 1;
int workSize = 0;
while (flag.get()) {
workerRouter.tell(MsgEnum.WORKING, ActorRef.noSender());
if (i % 3 == 0) {
workerRouter.tell(MsgEnum.CLOSE, ActorRef.noSender());
workSize++;
if (workSize >= 3) {
flag.set(false);
}
}
Thread.sleep(1000);
i++;
}
system.terminate();
}
}
运行结果
[INFO] [08/10/2017 18:10:06.696] [System-akka.actor.default-dispatcher-4] [akka://System/user/RouterTest/$a] i am working.
[INFO] [08/10/2017 18:10:07.687] [System-akka.actor.default-dispatcher-4] [akka://System/user/RouterTest/$b] i am working.
[INFO] [08/10/2017 18:10:08.687] [System-akka.actor.default-dispatcher-4] [akka://System/user/RouterTest/$c] i am working.
[INFO] [08/10/2017 18:10:08.688] [System-akka.actor.default-dispatcher-4] [akka://System/user/RouterTest/$a] i am close.akka://System/user/RouterTest/$a
[INFO] [08/10/2017 18:10:09.699] [System-akka.actor.default-dispatcher-3] [akka://System/user/RouterTest/$b] i am working.
[INFO] [08/10/2017 18:10:10.699] [System-akka.actor.default-dispatcher-3] [akka://System/user/RouterTest/$c] i am working.
[INFO] [08/10/2017 18:10:11.699] [System-akka.actor.default-dispatcher-2] [akka://System/user/RouterTest/$c] i am close.akka://System/user/RouterTest/$c
[INFO] [08/10/2017 18:10:11.699] [System-akka.actor.default-dispatcher-3] [akka://System/user/RouterTest/$b] i am working.
[INFO] [08/10/2017 18:10:12.703] [System-akka.actor.default-dispatcher-6] [akka://System/user/RouterTest/$b] i am working.
[INFO] [08/10/2017 18:10:13.702] [System-akka.actor.default-dispatcher-3] [akka://System/user/RouterTest/$b] i am working.
[INFO] [08/10/2017 18:10:14.702] [System-akka.actor.default-dispatcher-3] [akka://System/user/RouterTest/$b] i am working.
[INFO] [08/10/2017 18:10:14.702] [System-akka.actor.default-dispatcher-3] [akka://System/user/RouterTest/$b] i am close.akka://System/user/RouterTest/$b