1.mailbox

Akka的每个actor默认有一个mailbox,按照FIFO顺序单线程处理。在抛出异常导致父actor根据设置的监管策略执行重启或恢复操作时,会从触发异常的消息的后续消息开始处理,邮箱并不会被清空。如果你想重新处理那个触发异常的消息,可以通过重写preRestart方法来访问该消息,java 中的preRestart参数为(Throwable reason, Option<Object> message),message.get()可以获得该消息(因为是从Option对象中get,所以可能为空),可以将该消息再次发给自己或做其它处理。

默认邮箱的大小没有限制,也就是内存的上限。可以设置bounded邮箱来限定大小,还可以设置邮箱以文件形式持久存储。

2.监管策略设置

  1)在actor类中重写supervisorStrategy()

  2)创建父actor时在Props参数中使用FromConfig.getInstance().withSupervisorStrategy(strategy).props(XXX)

可以使用下面的类来方便设置:

import akka.actor.AllForOneStrategy;
import akka.actor.OneForOneStrategy;
import akka.actor.SupervisorStrategy;
import akka.japi.Function;
import scala.concurrent.duration.Duration; import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit; import static akka.actor.SupervisorStrategy.escalate; /**
* Created by fyk on 16-4-2.
*/
public class StrategySetter {
private Map<Class<? extends Throwable>, SupervisorStrategy.Directive> map;
private boolean oneForOne;
private int maxNrOfRetries=5;
private Duration withinTimeRange=Duration.create(1, TimeUnit.MINUTES);//Duration.create("1 minute")
public StrategySetter(boolean oneForOne) {
this.oneForOne=oneForOne;
map=new HashMap<Class<? extends Throwable>, SupervisorStrategy.Directive>();
}
public void setOptParam(int maxNrOfRetries,Duration withinTimeRange){
this.maxNrOfRetries=maxNrOfRetries;
this.withinTimeRange=withinTimeRange;
}
public void put(Class<? extends Throwable> t, SupervisorStrategy.Directive action){
map.put(t,action);
}
/**
* 设定监管策略并返回
* cls.isInstance(yourObject)
* instead of using the instanceof operator, which can only be used if you know the class at compile time.
*/
public SupervisorStrategy getSupervisorStrategy(){
SupervisorStrategy strategy=null;
if(oneForOne){
strategy=new OneForOneStrategy(maxNrOfRetries, withinTimeRange,
new Function<Throwable, SupervisorStrategy.Directive>() {
@Override
public SupervisorStrategy.Directive apply(Throwable t) {
for(Class c:map.keySet()){
if(c.isInstance(t)) return map.get(c);
}
return escalate();//提交给上一级监管
}
});
}else{
strategy=new AllForOneStrategy(maxNrOfRetries, withinTimeRange,
new Function<Throwable, SupervisorStrategy.Directive>() {
@Override
public SupervisorStrategy.Directive apply(Throwable t) {
for(Class c:map.keySet()){
if(c.isInstance(t)) return map.get(c);
}
return escalate();//提交给上一级监管
}
});
} return strategy;
}
}

注意在进行某一个actor的重启时会调用postStop、构造函数与preStart、preRestart等,在重写父类的方法时记得在第一句调用父类的方法(会对子actor进行一些操作)。如果你在actor中创建了子actor,重启时也会重启子actor,如果在重写preStart中没有调用父类的preStart会导致子actor重复创建,由于akka不能创建同名的actor,会抛出name not unique的异常信息。

3.actor Monitor

监管策略中指定了时间区间内重启或恢复等操作的上限,达到指定出错频率后actor被停止,以后再也不运转了。

也许你想要监视actor的生命状态,当它发现有actor停止时进行一些操作,如发邮件通知你,或简单粗暴的重新创建运行。

生命周期monitor:

/**
* Created on 16-4-10.
* 此生命周期monitor与设置了监管策略的supervisor都可以对远程actor进行监督
*/
public class MonitorActor extends UntypedActor {
Logger log = LoggerFactory.getLogger(MonitorActor.class);
Map<ActorRef, ActorRef> monitoredActors =//<worker,supervisor>
new HashMap<ActorRef, ActorRef>();
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof Terminated) {
final Terminated t = (Terminated) message;
if (monitoredActors.containsKey(t.getActor())) {
ActorPath path=t.getActor().path();
log.info("Received Worker Actor Termination Message ->{}", path);
log.info("Sending message to Supervisor");
monitoredActors.get(t.getActor()).tell(
new DeadWorker(path),self());
}
} else if (message instanceof RegisterWorker) {
RegisterWorker msg = (RegisterWorker) message;
//下面这句是关键的注册语句,当被观察的actor结束时,本actor会收到akka.actor.Terminated消息
getContext().watch(msg.getWorker());
monitoredActors.put(msg.getWorker(), msg.getSupervisor());
} else {
unhandled(message);
}
}
}

使用:在worker actor初始化时向monitor发送RegisterWorker消息,包含对actor本身以及supervisor(一般为父actor)的引用。

4.默认管理策略

  • ActorInitializationException will stop the failing child actor
  • ActorKilledException will stop the failing child actor
  • Exception will restart the failing child actor
  • Other types of Throwable will be escalated to parent actor

如果想将自己的部分管理策略与默认管理策略结合,可以在一些异常处理中使用super.supervisorStrategy.decider.applyOrElse(t, (_: Any) => Escalate)

注意,当actor被重启时并不会发送Terminated消息给monitor,而context.stop(actor)才会

5.Akka-remote注意事项

Akka在接收到消息时根据邮箱地址也就是actor的地址来递送消息,本地的地址形式如/user/parent/childActor,远程的akka.tcp://RemoteSystem@host:port/user/xxx。寻址按照字符串匹配的形式,所以hostname与ip地址不能乱写,即使是指向相同的ip地址。

在向远程actor主动发送消息时需要使用ActorSelection的tell方法。而在接收到远程actor发来的消息后回复时使用sender.tell不一定能够发送成功,并且也没有发送到DeadLetter。最好使用ActorSelection(sender.path())来发送。

x.continue...

Akka框架使用注意点的更多相关文章

  1. Scala的Actor模式 & Akka框架

    今天学Spark的时候,看到Scala的actor模式是一个加分点.所以搜了一下,看了.主要参考下面两篇文章,还没有实验,有些地方领会的不深刻: http://nxlhero.blog.51cto.c ...

  2. akka框架——异步非阻塞高并发处理框架

    akka actor, akka cluster akka是一系列框架,包括akka-actor, akka-remote, akka-cluster, akka-stream等,分别具有高并发处理模 ...

  3. akka框架地址

    http://doc.akka.io/docs/akka/2.2.3/AkkaJava.pdf

  4. 分布式应用框架Akka快速入门

    转自:http://blog.csdn.net/jmppok/article/details/17264495 本文结合网上一些资料,对他们进行整理,摘选和翻译而成,对Akka进行简要的说明.引用资料 ...

  5. 大数据学习day16------第三阶段-----scala04--------1. 模式匹配和样例类 2 Akka通信框架

    1. 模式匹配和样例类 Scala有一个十分强大的模式匹配机制,可以应用到很多场合:如switch语句.类型检查等.并且Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配 1.1 模式匹 ...

  6. Actor-ES框架:Ray

    并发 1. 并发和并行 并发:两个或多个任务在同一时间段内运行.关注点在任务分割. 并行:两个或多个任务在同一时刻同时运行.关注点在同时执行. 本文大多数情况下不会严格区分这两个概念,默认并发就是指并 ...

  7. Spark RPC框架源码分析(一)简述

    Spark RPC系列: Spark RPC框架源码分析(一)运行时序 Spark RPC框架源码分析(二)运行时序 Spark RPC框架源码分析(三)运行时序 一. Spark rpc框架概述 S ...

  8. Scala使用Akka模拟RPC机制代码2

    RemoteMessage.scala //对象要序列化才能通过网络传输 这个地方没有大括号....这有这个extends声明 trait RemoteMessage extends Serializ ...

  9. Akka概念集

    (转)http://www.csdn.net/article/2014-12-17/2823174 在Akka里面,和Actor通信的唯一方式就是通过ActorRef.ActorRef代表Actor的 ...

随机推荐

  1. Masonry使用注意事项

    1 理解自身内容尺寸约束与抗压抗拉 自身内容尺寸约束:一般来说,要确定一个视图的精确位置,至少需要4个布局约束(以确定水平位置x.垂直位置y.宽度w和高度h).但是,某些用来展现内容的用户控件,例如文 ...

  2. Java和WebSocket开发网页聊天室

    小编心语:咳咳咳,今天又是聊天室,到现在为止小编已经分享了不下两个了,这一次跟之前的又不大相同,这一次是网页聊天室,具体怎么着,还请各位看官往下看~ Java和WebSocket开发网页聊天室 一.项 ...

  3. canvas 绘制圆角矩形

    <!DOCTYPE HTML> <head> <meta charset = "utf-8"> <title>canvas</ ...

  4. 将ASP.NET Core应用程序部署至生产环境中(CentOS7)

    这段时间在使用Rabbit RPC重构公司的一套系统(微信相关),而最近相关检验(逻辑测试.压力测试)已经完成,接近部署至线上生产环境从而捣鼓了ASP.NET Core应用程序在CentOS上的部署方 ...

  5. JVM之SerialOld收集器

    Serial收集器的老年代版本 单线程收集器 标记-整理算法 stop the world Client模式下的虚拟机使用 Server模式下,搭配Parallel Scavenge使用及CMS发生C ...

  6. hdu 5641 King's Phone

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5641 题目类型:水题 题目思路:将点x到点y所需要跨过的点存入mark[x][y]中(无需跨过其它点存 ...

  7. EcmaScript相关文档

    ecmascript5.1中文文档 ECMAScript 6入门 JavaScript 标准参考教程 ECMAScript 5.1简介 ES5中新增的Array方法详细说明 firefox社区java ...

  8. linux中inode、软链接、硬链接

    1 软链接 linux中软链接理解成window中的快捷方式.创建软链接的命令 ln -s 源文文件或目录 目标文件或目录 2 硬链接 创建硬链接的命令如下 ln  源文文件或目录 目标文件或目录 3 ...

  9. MalformedByteSequenceException: Invalid byte 1 of 1-byte

    修改了线上程序的xml配置文件,重启后报如下错误: MalformedByteSequenceException: Invalid byte 1 of 1-byte 百度了下大体的意思是说文件的编码错 ...

  10. Neutron 理解(14):Neutron ML2 + Linux bridge + VxLAN 组网

    学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...