Akka Quickstart with Java-笔记

Posted Jayson

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Akka Quickstart with Java-笔记相关的知识,希望对你有一定的参考价值。

官方文档: http://developer.lightbend.com/guides/akka-quickstart-java/?_ga=2.177525157.1012573474.1504767665-546319647.1504766934

一. AKKA Hello World example : 

1.首先需要创建一个ActorSystem, 它是所有Actor运行的容器.

2.其次创建Greeter Actor和Printer Actor.

3.发送消息到Greeter Actor实例, 它们会先在内部存储消息.

4.最后Greeter Actor里面的指令消息会触发它们发送消息给Printer Actor, 然后Printer Actor会执行对应的操作.

 

 二. 定义Actors和messages

messages可以是任意类型(any subtype of Object).

当定义Actors和它们的messages时, 要遵守以下规范:

1.因为messages是Actor的公共API, 所以给messages定义名称的时候要富含语义以及特定领域的意义.

2.messages是不可变的, 因为它们在不同的线程之间共享.

3.把Actor相关的messages作为静态内部类放到Actor类中, 这样更容易理解actor需要处理什么类型的消息.

4.在Actor类中, 使用静态方法props描述如何构造Actor.

 1 package com.lightbend.akka.sample;
 2 
 3 import akka.actor.AbstractActor;
 4 import akka.actor.ActorRef;
 5 import akka.actor.Props;
 6 import com.lightbend.akka.sample.Printer.Greeting;
 7 
 8 public class Greeter extends AbstractActor {
 9   static public Props props(String message, ActorRef printerActor) {
10     return Props.create(Greeter.class, () -> new Greeter(message, printerActor));
11   }
12 
13   static public class WhoToGreet {
14     public final String who;
15 
16     public WhoToGreet(String who) {
17         this.who = who;
18     }
19   }
20 
21   static public class Greet {
22     public Greet() {
23     }
24   }
25 
26   private final String message;
27   private final ActorRef printerActor;
28   private String greeting = "";
29 
30   public Greeter(String message, ActorRef printerActor) {
31     this.message = message;
32     this.printerActor = printerActor;
33   }
34 
35   @Override
36   public Receive createReceive() {
37     return receiveBuilder()
38         .match(WhoToGreet.class, wtg -> {
39           this.greeting = message + ", " + wtg.who;
40         })
41         .match(Greet.class, x -> {
42           printerActor.tell(new Greeting(greeting), getSelf());
43         })
44         .build();
45   }
46 }
 1 package com.lightbend.akka.sample;
 2 
 3 import akka.actor.AbstractActor;
 4 import akka.actor.ActorRef;
 5 import akka.actor.Props;
 6 import akka.event.Logging;
 7 import akka.event.LoggingAdapter;
 8 
 9 public class Printer extends AbstractActor {
10   static public Props props() {
11     return Props.create(Printer.class, () -> new Printer());
12   }
13 
14   static public class Greeting {
15     public final String message;
16 
17     public Greeting(String message) {
18       this.message = message;
19     }
20   }
21 
22   private LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
23 
24   public Printer() {
25   }
26 
27   @Override
28   public Receive createReceive() {
29     return receiveBuilder()
30         .match(Greeting.class, greeting -> {
31             log.info(greeting.message);
32         })
33         .build();
34   }
35 }

三.创建Actor对象

Actor不能用过new来创建, 而是通过工厂来创建Actor对象, 工厂返回的不是actor实例, 而是一个引用akka.actor.ActorRef, 这个引用指向actor实例.

akka.actor.ActorSystem类似于Spring的BeanFactory. 它作为Actor的容器, 管理actor的生命周期. 工厂方法actorOf通过两个参数创建Actor对象, 一个参数是配置对象Props, 一个参数是actor的名称.

1 final ActorRef printerActor = 
2   system.actorOf(Printer.props(), "printerActor");
3 final ActorRef howdyGreeter = 
4   system.actorOf(Greeter.props("Howdy", printerActor), "howdyGreeter");
5 final ActorRef helloGreeter = 
6   system.actorOf(Greeter.props("Hello", printerActor), "helloGreeter");
7 final ActorRef goodDayGreeter = 
8   system.actorOf(Greeter.props("Good day", printerActor), "goodDayGreeter");

四. 异步通信

Actor是响应式的和消息驱动的. 一个Actor不会做任何事情知道它接收到一个消息.Actors通过异步消息来通信. 这确保了消息的发送者(sender)不用停下来等待它们的消息被接受者(recipient)处理. 相反的, 发送者只要把消息放到接收者的邮筒(mailbox)里后就可以去干别的事了. 而这个邮筒本子上是一个有序的消息队列. 来自同一个Actor的多条消息是有序的, 而来自不同的Actor的消息是交错的.

当actor不处理消息的时候是处于一个暂停的状态, 此时它不消耗除内存以外的任何资源.

五. 发送消息到Actor

把消息放到Actor的邮筒(mailbox)里, 需要调用ActorRef的tell方法.  举个栗子:

把消息发送给Greeter Actor :

 1 howdyGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender());
 2 howdyGreeter.tell(new Greet(), ActorRef.noSender());
 3 
 4 howdyGreeter.tell(new WhoToGreet("Lightbend"), ActorRef.noSender());
 5 howdyGreeter.tell(new Greet(), ActorRef.noSender());
 6 
 7 helloGreeter.tell(new WhoToGreet("Java"), ActorRef.noSender());
 8 helloGreeter.tell(new Greet(), ActorRef.noSender());
 9 
10 goodDayGreeter.tell(new WhoToGreet("Play"), ActorRef.noSender());
11 goodDayGreeter.tell(new Greet(), ActorRef.noSender());

Greeter Actor给Printer Actor发送消息:

printerActor.tell(new Greeting(greeting), getSelf());

 

以上是关于Akka Quickstart with Java-笔记的主要内容,如果未能解决你的问题,请参考以下文章

SDP:Streaming-Data-Processor - Data Processing with Akka-Stream

AKKA文档2.1(java版)——什么是AKKA?

AKKA文档2.2(java)——术语,概念

AKKA文档(java版)

Java Akka Actor 和流

使用 Java 的 Akka 远程路由