Akka框架使用注意点
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框架使用注意点的更多相关文章
- Scala的Actor模式 & Akka框架
今天学Spark的时候,看到Scala的actor模式是一个加分点.所以搜了一下,看了.主要参考下面两篇文章,还没有实验,有些地方领会的不深刻: http://nxlhero.blog.51cto.c ...
- akka框架——异步非阻塞高并发处理框架
akka actor, akka cluster akka是一系列框架,包括akka-actor, akka-remote, akka-cluster, akka-stream等,分别具有高并发处理模 ...
- akka框架地址
http://doc.akka.io/docs/akka/2.2.3/AkkaJava.pdf
- 分布式应用框架Akka快速入门
转自:http://blog.csdn.net/jmppok/article/details/17264495 本文结合网上一些资料,对他们进行整理,摘选和翻译而成,对Akka进行简要的说明.引用资料 ...
- 大数据学习day16------第三阶段-----scala04--------1. 模式匹配和样例类 2 Akka通信框架
1. 模式匹配和样例类 Scala有一个十分强大的模式匹配机制,可以应用到很多场合:如switch语句.类型检查等.并且Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配 1.1 模式匹 ...
- Actor-ES框架:Ray
并发 1. 并发和并行 并发:两个或多个任务在同一时间段内运行.关注点在任务分割. 并行:两个或多个任务在同一时刻同时运行.关注点在同时执行. 本文大多数情况下不会严格区分这两个概念,默认并发就是指并 ...
- Spark RPC框架源码分析(一)简述
Spark RPC系列: Spark RPC框架源码分析(一)运行时序 Spark RPC框架源码分析(二)运行时序 Spark RPC框架源码分析(三)运行时序 一. Spark rpc框架概述 S ...
- Scala使用Akka模拟RPC机制代码2
RemoteMessage.scala //对象要序列化才能通过网络传输 这个地方没有大括号....这有这个extends声明 trait RemoteMessage extends Serializ ...
- Akka概念集
(转)http://www.csdn.net/article/2014-12-17/2823174 在Akka里面,和Actor通信的唯一方式就是通过ActorRef.ActorRef代表Actor的 ...
随机推荐
- 在CentOS7上安装JDK1.8
在CentOS7上安装JDK1.8 1 通过 SecureCRT 连接到阿里云 CentOS7 服务器: 2 进入到目录 /usr/local/ 中: cd /usr/local/ 3 创建目录 to ...
- SSDT旧版本对于xml数据的处理BUG
在早期版本中,CLR中声明sqlxml时,SSDT会将CLR函数中使用的类型解析为NVARCHAR(4000),最终导致传向CLR函数的数据不完整
- shell
查看本机的shell有哪些 cat /etc/shells切换shell(zsh) chsh -s /bin/zsh 切换默认shell(bash) chsh -s /bin/bash
- mysql: unknown variable 'character-set-client=utf8'
在同事安装的MySQL服务器上(居然安装的是My-SQL 5.1.73的老旧版本),登录MySQL时遇到下面"mysql: unknown variable 'character-set-c ...
- 从零自学Hadoop(03):Linux准备上
阅读目录 序 检查列表 常用Linux命令 搭建环境 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,Sou ...
- CentOS 6.8 LAMP 安装配置
1.远程系统拒绝了连接: 需要关闭防火墙/etc/rc.d/init.d/iptables stop service iptables stop chkconfig iptables off sete ...
- Linux基础命令操作
显示日期与时间:date date +%Y/%m/%d date +%H:%M 显示日历:cal 显示一整年(cal 2009) 显示一年中的某一个月 (cal [[month]] year) 例如 ...
- 关于ActionBar
添加ActionBar: Android 3.0(API 11)(不含API11)以下的版本中,如果需要活动有ActionBar,需要让活动继承ActionBarActivity类,并且在Manife ...
- JS入门学习,写一个简单的选项卡
/* 经过昨天一整天的纠结和摸索.总结下学习初期我最致命的几个问题…… 1.var oDiv = document.getElementById(''); 一定要多输,熟悉后o u什么的字母别搞 ...
- 【CSS】其他CSS属性和特性
1. 设置元素的颜色和透明度 前面有介绍CSS颜色的各种用法,如 background-color属性.boder-color属性等.还有另外两个与颜色有关的属性. 1.1 设置前景色 color属性 ...