官方文档的quick start 官方链接
我将代码放到了这个github仓库 通过这个demo 对于akka使用actor模型 发送消息的一些注意事项,以及语法有了很多了解
定义actor建议
当定义actor和他的消息的时候记住以下建议:
- 因为消息是Actor的公共API,好的实践是使用好的名称,丰富的语义和领域特定的含义来定义消息.即使他们只包裹了你的数据类型.这也将更容易的使用,理解以及调试 基于actor的系统。
- 消息应该是不变的,因为他们在多个不同的线程间共享.
- 把一个actor的关联消息如同静态类放在 AbstractBehavior's类中是一个好的实践。这使得它更容易被理解,这个actor处理和期望什么类型的消息.
- 使用一个静态工厂方法去获得一个actor的初始化是一个好的实践.
位置透明的强大之处
在Akka中你不能够通new关键字来创建一个Actor.取而代之的是使用工厂的spawn方法创建Actor.Spawn不会返回一个actor实例,而是一个引用.akka.actor.typed.ActorRef 指向一个actor实例,这种级别的间接访问使得在分布式系统中更加强大和灵活.
在Akka中定位并不重要.定位透明意味着 ActorRef可以在保留同样语义的情况下,同时代表一个跑在进程中的或者远程机器中的actor.
如果需要,The runtime 可以在运行时通过改变Actor的位置或者整个应用拓扑来优化系统. 这使得失败管理的模型"let it crash" 在系统中可以通过 奔溃(crashing) 失败Actor 和重启健康的actor 来让系统修复.
异步通信
Actors 是响应式和消息驱动得.一个Actor在没有收到消息前不做任何事情.Actors通过异步消息通信,所以发送者不会在接收者处理消息前一直阻塞.取而代之得是,发送者把消息放入接收者的邮箱然后可以干别的事情了.
Actors的邮箱本质上是具有排队语义的消息队列. 从一个Actor发送过来的消息顺序将被保留,但是多个actor发送的消息可能会交织在一起.。
在Actors没有处理消息的时候他们在干什么? 他们处于暂停状态,除了内存以外 不消耗任何资源. 这也表现了actor的轻量和时效性.
给actor发送消息
通过ActorRef的 tell()方法 把消息放到actor的邮箱里面,
command.replyTo.tell(new Greeted(command.whom, getContext().getSelf()));//回复消息
greeterMain.tell(new GreeterMain.SayHello("Charles"));//发送消息
ActorSystem
final ActorSystem<GreeterMain.SayHello> greeterMain =ActorSystem.create(GreeterMain.create(), "helloakka");
ActorSystem是一个进入Akka的初始入点.他是一个重量级的对象,其中包含了信箱、线程池,所以每个应用只需要创建一个即可.
一个ActorSystem 有一个名称和一个守护(guardian)actor. 应用的启动通常在守护actor中完成.
代码中ActorSystem的守护Actor是GreeterMain.
通过下面方法 开始引导应用
Behaviors.setup(GreeterMain::new);
创建子Actor
其他actor 通过spawn(actor,name)方法再ActorContext上创建.
GreeterMain启动的时候创建actor,
greeter = context.spawn(Greeter.create(), "greeter");
在收到消息的时候创建
下面代码是创建一个新的actor 并且发送消息-该消息带了一个GreeterBot的引用
ActorRef<Greeter.Greeted> replyTo =
getContext().spawn(GreeterBot.create(3), command.name);
greeter.tell(new Greeter.Greet(command.name, replyTo));
Greeter:
实现了Greeter Actor:
定义了两个消息类型,
- Greet: 除了持有 (whom)谁通知的信息 也持有了 actorRef(发送消息的人提供的引用 所以Greeter Actor可以发送回来确认消息)
- Greeted: 和Greet类似,但是方向相反.
方法:
createReceive():
Actor的行为由实现 AbstractBehavior的createReceive()方法定义,通过newReceiveBuilder ()行为工厂的帮助.
onGreet():
处理下一个消息然后返回一个新的行为,这个行为可能与当前这个行为不同(当前例子没啥改变就返回了自身)
当前行为声明的Greet类是当前Actor处理的消息类型.通常一个actor处理多种特定类型消息 并且他们有一个共同的接口,当前Actor可以处理他的所有实现.
command.replyTo.tell(new Greeted(command.whom, getContext().getSelf()));
Greeter Actor 给别的actor发送消息, 使用tell方法是一个异步操作不会阻塞调用者线程.
当replyTo 的地址被 ActorRef<Greeted> 声明,编译这将只语序我们发送这个类型的消息,其他类型将会编译错误.
一个actor接受的消息类型和所有回复类型定义了 这个Actor的口头协议.这个case 是一个简单的 请求回复协议,当我们需要时Actors可以为任意复杂(arbitrarily complex protocols)模型建模.协议和它的行为捆绑在一起形成了一个包装良好的作用域- Greeter class
GreeterBot
有一个实例变量管理计数器.并不需要并发防卫 比如 synchronized 或AtomicInteger ,一个actor 实例在同一时刻只处理一个消息.
GreeterMain
该类是第三个actor,他产生了Greeter 和 GreeterBot 并且开始交互.