Akka学习笔记
来源:互联网 发布:打字赚钱的软件 编辑:程序博客网 时间:2024/05/16 15:49
持续更新中….
目录
- Akka官网
- Part 1 Actor结构
- Actor的层次结构
- Actor的生命周期
- 失败处理
- Part 2 Actors
- 创建Actors
- 定义一个Actor类
- Props
- 使用Props创建Actors
- 依赖注入
- Inbox
- Actor API
- ActorSelection
- Lifecycle Monitoring aka DeathWatch
- Identifying Actors via Actor Selection
- 消息和不变性Immutability
- 发送消息
- 接收消息
- 接收超时时间
- 关闭Actor
- PoisonPill
- 杀死Actor
- 优雅的关闭
- BecomeUnbecome
- Stash
- 创建Actors
- Part3 Dispatchers
- Part4 Mailboxes
- Mailbox Selection
- Part5 Routes
Akka官网
https://doc.akka.io/docs/akka/current/guide
Part 1 Actor结构
Actor的层次结构
所有的Actor都有一个父级Actor,system.actorOf()方法在/user目录下创建Actor,contextOf()方法在父级Actor下创建Actor。
Actor的生命周期
当一个actor被关闭时,它的所有子节点也将会被递归地关闭。这样可以很好的避免资源的浪费还有资源的泄露,例如当子节点中有一些打开的socket或者文件。事实上,在处理低层次的多线程代码时,一个通常被忽视的困难是各种并发资源的生命周期管理。
为了停止一个参与者,推荐的模式是调用getContext().stop(getSelf())在actor中停止自身,通常作为对某个用户定义的停止消息的响应,或者当参与者完成它的工作时。从技术上讲,通过调用getContext().stop(actorRef)来阻止另一个参与者是可行的,但是阻止任意的行为者被认为是一种不好的做法:尝试给他们发送一个PoisonPill或自定义的停止消息,让收到消息的Actor自己停止。
Akka actor API公开了许多可以在actor实现中覆盖的生命周期hooks。最常用的是preStart()和postStop()。
preStart():在Actor开始之后,处理第一条消息之前调用
postStop():在Actor停止之后条用,一旦调用,将不会处理任何消息
失败处理
一旦一个actor出错(抛出一个异常或者在receive方法中抛出)它会暂停,子级的错误会抛给父级,然后父级觉得如何处理异常,父级是作为子级的监视者,Akka提供的默认的监视策略是停止子级然后重启它。
Part 2 Actors
Actor模型对于高并发的分布式系统提供了更高层次的抽象。它让开发者可以避免显式的使用锁和管理线程,使得开发一个正确的并发系统更加容易。
创建Actors
定义一个Actor类
import akka.actor.AbstractActor;import akka.event.Logging;import akka.event.LoggingAdapter;public class MyActor extends AbstractActor { private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this); @Override public Receive createReceive() { return receiveBuilder() .match(String.class, s -> { log.info("Received String message: {}", s); }) .matchAny(o -> log.info("received unknown message")) .build(); }}
Props
Props是一个配置类用于创建actor时提供具体的参数
import akka.actor.Props;Props props1 = Props.create(MyActor.class);Props props2 = Props.create(ActorWithArgs.class, () -> new ActorWithArgs("arg")); // careful, see belowProps props3 = Props.create(ActorWithArgs.class, "arg");
区别???待解决
使用Props创建Actors
通过将Props的实例传给ActorSystem或者ActorContext的工厂方法ActorOf来创建Actors。
import akka.actor.ActorRef;import akka.actor.ActorSystem;public class FirstActor extends AbstractActor { final ActorRef child = getContext().actorOf(Props.create(MyActor.class), "myChild"); @Override public Receive createReceive() { return receiveBuilder() .matchAny(x -> getSender().tell(x, getSelf())) .build(); }}
调用actorOf方法返回的是ActorRef的实例,他是actor实例的引用,是唯一操作Actor的方法。
依赖注入
Inbox
Actor API
ActorSelection
Lifecycle Monitoring aka DeathWatch
为了在另一个Actor终止(即永久停止,而不是临时失败和重新启动)时被通知,Actor可以注册自己,以接收由另一个Actor在终止时发送的终止消息。该服务由actorSystem的DeathWatch组件提供。
import akka.actor.Terminated;public class WatchActor extends AbstractActor { private final ActorRef child = getContext().actorOf(Props.empty(), "target"); private ActorRef lastSender = system.deadLetters(); public WatchActor() { getContext().watch(child); // <-- this is the only call needed for registration } @Override public Receive createReceive() { return receiveBuilder() .matchEquals("kill", s -> { getContext().stop(child); lastSender = getSender(); }) .match(Terminated.class, t -> t.actor().equals(child), t -> { lastSender.tell("finished", getSelf()); }) .build(); }}
也可以通过使用context.unwatch(target)来观察另一个Actor的活动轨迹。即使已终止的消息已经在邮箱中被排队,它也能正常工作;在调用unwatch后,将不再处理该actor的终止消息。
Identifying Actors via Actor Selection
消息和不变性(Immutability)
重要:消息可以是任何类型的对象,但是必须是不可变的,虽然Akka框架并没有在代码上强制要求。
发送消息
可以使用下面两个方法去发送消息:
- tell:是“fire-and-forget”模式,既异步的发送消息,然后立即返回
- ask:异步发送消息,然后返回一个代表返回值的Future对象
接收消息
接收超时时间
public class ReceiveTimeoutActor extends AbstractActor { public ReceiveTimeoutActor() { // To set an initial delay getContext().setReceiveTimeout(Duration.create(10, TimeUnit.SECONDS)); } @Override public Receive createReceive() { return receiveBuilder() .matchEquals("Hello", s -> { // To set in a response to a message getContext().setReceiveTimeout(Duration.create(1, TimeUnit.SECONDS)); }) .match(ReceiveTimeout.class, r -> { // To turn it off getContext().setReceiveTimeout(Duration.Undefined()); }) .build(); }}
关闭Actor
import akka.actor.ActorRef;import akka.actor.AbstractActor;public class MyStoppingActor extends AbstractActor { ActorRef child = null; // ... creation of child ... @Override public Receive createReceive() { return receiveBuilder() .matchEquals("interrupt-child", m -> getContext().stop(child) ) .matchEquals("done", m -> getContext().stop(getSelf()) ) .build(); }}
PoisonPill
你也可以发送一个akka.actor.PoisonPill。毒丸消息,当消息被处理时,它将停止Actor。毒丸作为普通消息排队,并将在邮箱中已经排队的消息后处理。
victim.tell(akka.actor.PoisonPill.getInstance(), ActorRef.noSender());
杀死Actor
你也可以发送一个Kill消息,它和毒丸消息不一样会抛出一个异常,这个Actor将会暂停操作,它的监视者将会被调用去处理这个异常,也许是恢复,重启或者完全关闭它。
victim.tell(akka.actor.Kill.getInstance(), ActorRef.noSender());// expecting the actor to indeed terminate:expectTerminated(Duration.create(3, TimeUnit.SECONDS), victim);
优雅的关闭
如果你需要等待终止或组合多个参与者的命令终止,那么gracefulStop方法是非常有用的。
try { CompletionStage<Boolean> stopped = gracefulStop(actorRef, Duration.create(5, TimeUnit.SECONDS), Manager.SHUTDOWN); stopped.toCompletableFuture().get(6, TimeUnit.SECONDS); // the actor has been stopped} catch (AskTimeoutException e) { // the actor wasn't stopped within 5 seconds}
Become/Unbecome
Stash
Part3 Dispatchers
Part4 Mailboxes
一个Akka的邮箱保存着相应Actor的消息,通常来说,每个Actor都有自己的邮箱,但是一个BalancingPool所有的路由都共享一个邮箱实例。
Mailbox Selection
Part5 Routes
- akka概念 学习笔记
- akka 学习笔记
- Akka 学习笔记
- Akka学习笔记:日志
- AKKA学习笔记
- AKKA学习笔记
- AKKA学习笔记
- AKKA学习笔记
- Akka学习笔记
- akka学习笔记(1)
- Akka学习笔记(2)
- Akka学习笔记(3)
- Akka学习笔记(4)
- akka 之 Dispatcher学习笔记
- Akka学习笔记:Actors介绍
- Akka学习笔记:测试Actors
- Akka学习笔记:ActorSystem(配置)
- Akka学习笔记:ActorSystem(调度)
- 参数签名实例(md5实现 数据完整性)
- 《算法设计与分析》实践报告--求两个有序序列的中位数
- otter系列—canal和otter的关系?
- ListView获取焦点,使页面无法从头开始展示
- Android监听软键盘,布局上移不遮挡输入框
- Akka学习笔记
- 验证数字的正则表达式
- C++const 关键字小结
- 扁平化多维数组
- LINTCODE——Digit Divide Numbers
- 爽文
- Javascript学习笔记(定时器)
- 数字 一阶低通滤波器 详细分析 冰三点水
- 安装zsh+oh-my-zsh及插件