├── README.MD
├── pom.xml
└── src
└── main
├── java
└── cn
│ └── sunxiang0918
│ └── akka
│ ├── demo1
│ ├── AkkaMain.java
│ ├── actor
│ │ ├── GreetPrinter.java
│ │ └── Greeter.java
│ └── model
│ │ ├── Greet.java
│ │ ├── Greeting.java
│ │ └── WhoToGreet.java
│ ├── demo1_5
│ ├── AkkaMain.java
│ └── actor
│ │ ├── Squarer.java
│ │ └── SquarerImpl.java
│ ├── demo2
│ ├── client
│ │ ├── ClientMain.java
│ │ └── actor
│ │ │ ├── ClientActor.java
│ │ │ └── FileReadActor.java
│ └── server
│ │ ├── MyPriorityMailBox.java
│ │ ├── WCMapReduceServer.java
│ │ ├── actor
│ │ ├── AggregateActor.java
│ │ ├── MapActor.java
│ │ ├── ReduceActor.java
│ │ └── WCMapReduceActor.java
│ │ └── model
│ │ └── Result.java
│ ├── demo3
│ ├── AkkaMain3.java
│ └── actor
│ │ ├── JobControllerActor.java
│ │ └── WorkerActor.java
│ ├── demo4
│ ├── AkkaMain4.java
│ ├── actor
│ │ ├── ReceiveActor.java
│ │ └── ResultActor.java
│ └── model
│ │ └── Result.java
│ ├── demo5
│ ├── AkkaMain5.java
│ ├── actor
│ │ ├── ControlActor.java
│ │ ├── VoteCountRouter.java
│ │ └── WriterActor.java
│ └── model
│ │ ├── ControlCommand.java
│ │ ├── ExecutionResult.java
│ │ ├── InsertCommand.java
│ │ └── StartCommand.java
│ ├── demo6
│ ├── SimpleClusterApp.java
│ ├── SimpleClusterListener.java
│ └── SimpleClusterListener2.java
│ ├── demo7
│ ├── FactorialApp.java
│ ├── FactorialBackend.java
│ ├── FactorialBackendMain.java
│ ├── FactorialFrontend.java
│ ├── FactorialFrontendMain.java
│ ├── FactorialResult.java
│ └── MetricsListener.java
│ ├── demo8
│ ├── ClusterRoledWorker.java
│ ├── Demo8App.java
│ ├── EventClient.java
│ ├── EventCollector.java
│ ├── EventInterceptor.java
│ ├── EventInterceptorMain.java
│ ├── EventMessages.java
│ ├── EventProcessor.java
│ ├── EventProcessorMain.java
│ └── kafka
│ │ ├── KafkaTemplate.java
│ │ ├── ObjectDecoder.java
│ │ └── ObjectEncoder.java
│ └── demo9
│ └── FutureTest.java
├── resources
├── Othello.txt
├── application.conf
├── client.conf
├── demo5.conf
├── demo6.conf
├── demo7.conf
└── demo8.conf
└── webapp
├── WEB-INF
└── web.xml
└── index.jsp
/README.MD:
--------------------------------------------------------------------------------
1 | AKKA In JAVA 的DEMO 代码.
2 | 相关文章为:
3 |
4 | * [Akka in JAVA(一)](http://sunxiang0918.cn/2016/01/10/Akka-in-JAVA-1/)
5 | * [Akka in JAVA(二)](http://sunxiang0918.cn/2016/01/13/Akka-in-JAVA-2/)
6 | * [Akka in JAVA(三)](http://sunxiang0918.cn/2016/01/18/Akka-in-JAVA-3/)
7 | * [Akka in JAVA(四)](http://sunxiang0918.cn/2016/02/10/Akka-in-JAVA-4/)
8 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | cn.sunxiang0918
5 | akkatest
6 | war
7 | 1.0-SNAPSHOT
8 | akkatest Maven Webapp
9 | http://maven.apache.org
10 |
11 |
12 | junit
13 | junit
14 | 4.12
15 | test
16 |
17 |
18 | com.typesafe.akka
19 | akka-actor_2.11
20 | 2.4.1
21 |
22 |
23 | com.typesafe.akka
24 | akka-remote_2.11
25 | 2.4.1
26 |
27 |
28 |
29 | com.typesafe.akka
30 | akka-cluster_2.11
31 | 2.4.1
32 |
33 |
34 |
35 | org.apache.httpcomponents
36 | httpclient
37 | 4.4.1
38 |
39 |
40 |
41 | com.alibaba
42 | fastjson
43 | 1.2.6
44 |
45 |
46 |
47 | org.apache.kafka
48 | kafka_2.11
49 | 0.9.0.0
50 |
51 |
52 | org.apache.kafka
53 | kafka-clients
54 | 0.9.0.0
55 |
56 |
57 |
58 |
59 | akkatest
60 |
61 |
62 | org.apache.maven.plugins
63 | maven-compiler-plugin
64 |
65 | 1.8
66 | 1.8
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo1/AkkaMain.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo1;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | import akka.actor.ActorRef;
6 | import akka.actor.ActorSelection;
7 | import akka.actor.ActorSystem;
8 | import akka.actor.Inbox;
9 | import akka.actor.Props;
10 | import cn.sunxiang0918.akka.demo1.actor.GreetPrinter;
11 | import cn.sunxiang0918.akka.demo1.actor.Greeter;
12 | import cn.sunxiang0918.akka.demo1.model.Greet;
13 | import cn.sunxiang0918.akka.demo1.model.Greeting;
14 | import cn.sunxiang0918.akka.demo1.model.WhoToGreet;
15 | import scala.concurrent.duration.Duration;
16 |
17 | /**
18 | * @author SUN
19 | * @version 1.0
20 | * @Date 16/1/6 21:39
21 | */
22 | public class AkkaMain {
23 |
24 | public static void main(String[] args) throws Exception {
25 | final ActorSystem system = ActorSystem.create("helloakka");
26 |
27 | // 创建一个到greeter Actor的管道
28 | final ActorRef greeter = system.actorOf(Props.create(Greeter.class), "greeter");
29 |
30 | System.out.println(greeter.path());
31 |
32 | final ActorSelection selection = system.actorSelection("akka://helloakka/user/greeter");
33 | selection.tell(new WhoToGreet("akka"), ActorRef.noSender());
34 |
35 | // 创建邮箱
36 | final Inbox inbox = Inbox.create(system);
37 |
38 | // 先发第一个消息,消息类型为WhoToGreet
39 | // greeter.tell(new WhoToGreet("akka"), ActorRef.noSender());
40 |
41 | // 真正的发送消息,消息体为Greet
42 | inbox.send(greeter, new Greet());
43 |
44 | // 等待5秒尝试接收Greeter返回的消息
45 | Greeting greeting1 = (Greeting) inbox.receive(Duration.create(5, TimeUnit.SECONDS));
46 | System.out.println("Greeting: " + greeting1.message);
47 |
48 | // 发送第三个消息,修改名字
49 | greeter.tell(new WhoToGreet("typesafe"), ActorRef.noSender());
50 | // 发送第四个消息
51 | inbox.send(greeter, new Greet());
52 |
53 | // 等待5秒尝试接收Greeter返回的消息
54 | Greeting greeting2 = (Greeting) inbox.receive(Duration.create(5, TimeUnit.SECONDS));
55 | System.out.println("Greeting: " + greeting2.message);
56 |
57 | // 新创建一个Actor的管道
58 | ActorRef greetPrinter = system.actorOf(Props.create(GreetPrinter.class));
59 |
60 | //使用schedule 每一秒发送一个Greet消息给 greeterActor,然后把greeterActor的消息返回给greetPrinterActor
61 | system.scheduler().schedule(Duration.Zero(), Duration.create(1, TimeUnit.SECONDS), greeter, new Greet(), system.dispatcher(), greetPrinter);
62 | //system.shutdown();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo1/actor/GreetPrinter.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo1.actor;
2 |
3 | import akka.actor.UntypedActor;
4 | import cn.sunxiang0918.akka.demo1.model.Greeting;
5 |
6 | /**
7 | * 打印招呼
8 | * @author SUN
9 | * @version 1.0
10 | * @Date 16/1/6 21:45
11 | */
12 | public class GreetPrinter extends UntypedActor{
13 |
14 | @Override
15 | public void onReceive(Object message) throws Exception {
16 | if (message instanceof Greeting)
17 | System.out.println(((Greeting) message).message);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo1/actor/Greeter.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo1.actor;
2 |
3 | import akka.actor.UntypedActor;
4 | import cn.sunxiang0918.akka.demo1.model.Greet;
5 | import cn.sunxiang0918.akka.demo1.model.Greeting;
6 | import cn.sunxiang0918.akka.demo1.model.WhoToGreet;
7 |
8 | /**
9 | * 打招呼的Actor
10 | * @author SUN
11 | * @version 1.0
12 | * @Date 16/1/6 21:40
13 | */
14 | public class Greeter extends UntypedActor{
15 |
16 | String greeting = "";
17 |
18 | @Override
19 | public void onReceive(Object message) throws Exception {
20 | if (message instanceof WhoToGreet)
21 | greeting = "hello, " + ((WhoToGreet) message).who;
22 | else if (message instanceof Greet)
23 | // 发送招呼消息给发送消息给这个Actor的Actor
24 | getSender().tell(new Greeting(greeting), getSelf());
25 |
26 | else unhandled(message);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo1/model/Greet.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo1.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 用于表示执行打招呼这个操作的消息
7 | * @author SUN
8 | * @version 1.0
9 | * @Date 16/1/6 21:43
10 | */
11 | public class Greet implements Serializable {
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo1/model/Greeting.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo1.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 招呼体,里面有打的什么招呼
7 | * @author SUN
8 | * @version 1.0
9 | * @Date 16/1/6 21:44
10 | */
11 | public class Greeting implements Serializable {
12 | public final String message;
13 | public Greeting(String message) {
14 | this.message = message;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo1/model/WhoToGreet.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo1.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 打招呼的人
7 | * @author SUN
8 | * @version 1.0
9 | * @Date 16/1/6 21:41
10 | */
11 | public class WhoToGreet implements Serializable {
12 | public final String who;
13 | public WhoToGreet(String who) {
14 | this.who = who;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo1_5/AkkaMain.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo1_5;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | import akka.actor.ActorSystem;
6 | import akka.actor.TypedActor;
7 | import akka.actor.TypedProps;
8 | import akka.japi.Creator;
9 | import akka.japi.Option;
10 | import cn.sunxiang0918.akka.demo1_5.actor.Squarer;
11 | import cn.sunxiang0918.akka.demo1_5.actor.SquarerImpl;
12 | import scala.concurrent.Await;
13 | import scala.concurrent.Future;
14 | import scala.concurrent.duration.Duration;
15 |
16 | /**
17 | * @author SUN
18 | * @version 1.0
19 | * @Date 16/1/24 13:57
20 | */
21 | public class AkkaMain {
22 |
23 | public static void main(String[] args) throws Exception {
24 | final ActorSystem system = ActorSystem.create("helloakka");
25 |
26 | /*默认构造方法的Actor*/
27 | Squarer mySquarer = TypedActor.get(system).typedActorOf(new TypedProps<>(Squarer.class, SquarerImpl.class));
28 |
29 | /*传参构造的Actor*/
30 | Squarer otherSquarer =
31 | TypedActor.get(system).typedActorOf(new TypedProps<>(Squarer.class,
32 | new Creator() {
33 | public SquarerImpl create() {
34 | return new SquarerImpl("foo");
35 | }
36 | }),
37 | "name");
38 |
39 |
40 | Option oSquare = mySquarer.squareNowPlease(10); //Option[Int]
41 | System.out.println("阻塞异步调用执行外面");
42 | //获取结果
43 | System.out.println(oSquare.get());
44 |
45 | Future fSquare = mySquarer.square(10); //A Future[Int]
46 | System.out.println("非阻塞异步执行外面");
47 | //等待5秒内返回结果
48 | System.out.println(Await.result(fSquare, Duration.apply(5, TimeUnit.SECONDS)));
49 |
50 | TypedActor.get(system).stop(mySquarer);
51 |
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo1_5/actor/Squarer.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo1_5.actor;
2 |
3 | import akka.japi.Option;
4 | import scala.concurrent.Future;
5 |
6 | /**
7 | * @author SUN
8 | * @version 1.0
9 | * @Date 16/1/24 13:53
10 | */
11 | public interface Squarer {
12 |
13 | Future square(int i); //non-blocking send-request-reply
14 |
15 | Option squareNowPlease(int i);//blocking send-request-reply
16 |
17 | int squareNow(int i); //blocking send-request-reply
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo1_5/actor/SquarerImpl.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo1_5.actor;
2 |
3 | import akka.dispatch.Futures;
4 | import akka.japi.Option;
5 | import scala.concurrent.Future;
6 |
7 | /**
8 | * @author SUN
9 | * @version 1.0
10 | * @Date 16/1/24 13:55
11 | */
12 | public class SquarerImpl implements Squarer {
13 |
14 | private String name;
15 |
16 | public SquarerImpl() {
17 | this.name = "default";
18 | }
19 |
20 | public SquarerImpl(String name) {
21 | this.name = name;
22 | }
23 |
24 | public Future square(int i) {
25 | return Futures.successful(squareNow(i));
26 | }
27 |
28 | public Option squareNowPlease(int i) {
29 | return Option.some(squareNow(i));
30 | }
31 |
32 | public int squareNow(int i) {
33 | try {
34 | Thread.sleep(100);
35 | } catch (InterruptedException e) {
36 | e.printStackTrace();
37 | }
38 | System.out.println("执行里面");
39 | return i * i;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo2/client/ClientMain.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo2.client;
2 |
3 | import akka.actor.ActorRef;
4 | import akka.actor.ActorSystem;
5 | import akka.actor.Props;
6 | import cn.sunxiang0918.akka.demo2.client.actor.ClientActor;
7 | import cn.sunxiang0918.akka.demo2.client.actor.FileReadActor;
8 | import com.typesafe.config.ConfigFactory;
9 |
10 | /**
11 | * @author SUN
12 | * @version 1.0
13 | * @Date 16/1/7 10:19
14 | */
15 | public class ClientMain {
16 |
17 | public static void main(String[] args) throws Exception {
18 |
19 | //文件名
20 | final String fileName = "Othello.txt";
21 |
22 | /*根据配置,找到System*/
23 | ActorSystem system = ActorSystem.create("ClientApplication", ConfigFactory.load("client").getConfig("WCMapReduceClientApp"));
24 |
25 | /*实例化远程Actor*/
26 | final ActorRef remoteActor = system.actorFor("akka.tcp://WCMapReduceApp@127.0.0.1:2552/user/WCMapReduceActor");
27 |
28 | /*实例化Actor的管道*/
29 | final ActorRef fileReadActor = system.actorOf(Props.create(FileReadActor.class));
30 |
31 | /*实例化Client的Actor管道*/
32 | final ActorRef clientActor = system.actorOf(Props.create(ClientActor.class,remoteActor));
33 |
34 | /*发送文件名给fileReadActor.设置sender或者说回调的Actor为clientActor*/
35 | fileReadActor.tell(fileName,clientActor);
36 |
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo2/client/actor/ClientActor.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo2.client.actor;
2 |
3 | import akka.actor.ActorRef;
4 | import akka.actor.UntypedActor;
5 |
6 | /**
7 | * @author SUN
8 | * @version 1.0
9 | * @Date 16/1/7 10:20
10 | */
11 | public class ClientActor extends UntypedActor {
12 |
13 | private ActorRef remoteServer = null;
14 | private long start;
15 |
16 | /**
17 | * @param inRemoteServer
18 | */
19 | public ClientActor(ActorRef inRemoteServer) {
20 | remoteServer = inRemoteServer;
21 | }
22 |
23 | @Override
24 | public void onReceive(Object message) throws Exception {
25 | /*如果接收到的任务是String的,那么就直接发送给remoteServer这个Actor*/
26 | if (message instanceof String) {
27 | String msg = (String) message;
28 | if (message.equals("EOF")){
29 | //这个的Sender设置为自己是为了接收聚合完成的消息
30 | remoteServer.tell(msg, getSelf());
31 | }else{
32 | remoteServer.tell(msg, null);
33 | }
34 | }else if (message instanceof Boolean) {
35 | System.out.println("聚合完成");
36 | //聚合完成后发送显示结果的消息
37 | remoteServer.tell("DISPLAY_LIST",null);
38 |
39 | //执行完毕,关机
40 | getContext().stop(self());
41 | }
42 | }
43 |
44 | @Override
45 | public void preStart() {
46 | /*记录开始时间*/
47 | start = System.currentTimeMillis();
48 | }
49 |
50 | @Override
51 | public void postStop() {
52 | /*计算用时*/
53 | // tell the world that the calculation is complete
54 | long timeSpent = (System.currentTimeMillis() - start);
55 | System.out
56 | .println(String
57 | .format("\n\tClientActor estimate: \t\t\n\tCalculation time: \t%s MS",
58 | timeSpent));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo2/client/actor/FileReadActor.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo2.client.actor;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 |
7 | import akka.actor.UntypedActor;
8 |
9 | /**
10 | * 从文件里面获取出行数
11 | *
12 | * @author SUN
13 | * @version 1.0
14 | * @Date 16/1/6 22:25
15 | */
16 | public class FileReadActor extends UntypedActor {
17 |
18 | @Override
19 | public void onReceive(Object message) throws Exception {
20 | if (message instanceof String) {
21 | /*如果消息是String类型的*/
22 | String fileName = (String) message;
23 | try {
24 | BufferedReader reader = new BufferedReader(
25 | new InputStreamReader(Thread.currentThread().getContextClassLoader().getResource(fileName).openStream()));
26 | String line;
27 | while ((line = reader.readLine()) != null) {
28 | /*遍历,一行一个消息反馈给消息发送方*/
29 | getSender().tell(line,null);
30 | }
31 | System.out.println("All lines send !");
32 | /*发送一个结束标识*/
33 | getSender().tell(String.valueOf("EOF"),null);
34 | } catch (IOException x) {
35 | System.err.format("IOException: %s%n", x);
36 | }
37 | } else {
38 | throw new IllegalArgumentException("Unknown message [" + message + "]");
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo2/server/MyPriorityMailBox.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo2.server;
2 |
3 | import akka.actor.ActorSystem;
4 | import akka.actor.PoisonPill;
5 | import akka.dispatch.PriorityGenerator;
6 | import akka.dispatch.UnboundedPriorityMailbox;
7 | import com.typesafe.config.Config;
8 |
9 | /**
10 | * @author SUN
11 | * @version 1.0
12 | * @Date 16/1/7 13:32
13 | */
14 | public class MyPriorityMailBox extends UnboundedPriorityMailbox {
15 |
16 | /**
17 | * 创建一个自定义优先级的无边界的邮箱. 用来规定命令的优先级. 这个就保证了DISPLAY_LIST 这个事件是最后再来处理.
18 | */
19 | public MyPriorityMailBox(ActorSystem.Settings settings, Config config) {
20 |
21 | // Creating a new PriorityGenerator,
22 | super(new PriorityGenerator() {
23 | @Override
24 | public int gen(Object message) {
25 | if (message.equals("DISPLAY_LIST"))
26 | return 2; // 'DisplayList messages should be treated
27 | // last if possible
28 | else if (message.equals(PoisonPill.getInstance()))
29 | return 3; // PoisonPill when no other left
30 | else
31 | return 0; // By default they go with high priority
32 | }
33 | });
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo2/server/WCMapReduceServer.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo2.server;
2 |
3 | import akka.actor.ActorRef;
4 | import akka.actor.ActorSystem;
5 | import akka.actor.Props;
6 | import akka.routing.RoundRobinPool;
7 | import cn.sunxiang0918.akka.demo2.server.actor.AggregateActor;
8 | import cn.sunxiang0918.akka.demo2.server.actor.MapActor;
9 | import cn.sunxiang0918.akka.demo2.server.actor.ReduceActor;
10 | import cn.sunxiang0918.akka.demo2.server.actor.WCMapReduceActor;
11 | import com.typesafe.config.ConfigFactory;
12 |
13 | /**
14 | * @author SUN
15 | * @version 1.0
16 | * @Date 16/1/7 10:43
17 | */
18 | public class WCMapReduceServer{
19 |
20 | private ActorRef mapRouter;
21 | private ActorRef reduceRouter;
22 | private ActorRef aggregateActor;
23 | private ActorRef wcMapReduceActor;
24 |
25 | public WCMapReduceServer(int no_of_reduce_workers, int no_of_map_workers) {
26 | /*创建了Actor系统*/
27 | ActorSystem system = ActorSystem.create("WCMapReduceApp", ConfigFactory.load("application")
28 | .getConfig("WCMapReduceApp"));
29 |
30 | // 创建聚合Actor
31 | aggregateActor = system.actorOf(Props.create(AggregateActor.class));
32 |
33 | // 创建多个聚合的Actor
34 | reduceRouter = system.actorOf(Props.create(ReduceActor.class,aggregateActor).withRouter(new RoundRobinPool(no_of_reduce_workers)));
35 |
36 | // 创建多个Map的Actor
37 | mapRouter = system.actorOf(Props.create(MapActor.class,reduceRouter).withRouter(new RoundRobinPool(no_of_map_workers)));
38 |
39 | // create the overall WCMapReduce Actor that acts as the remote actor
40 | // for clients
41 | Props props = Props.create(WCMapReduceActor.class,aggregateActor,mapRouter).withDispatcher("priorityMailBox-dispatcher");
42 | wcMapReduceActor = system.actorOf(props, "WCMapReduceActor");
43 | }
44 |
45 | /**
46 | * @param args
47 | */
48 | public static void main(String[] args) {
49 | new WCMapReduceServer(50, 50);
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo2/server/actor/AggregateActor.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo2.server.actor;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import akka.actor.UntypedActor;
7 |
8 | /**
9 | * @author SUN
10 | * @version 1.0
11 | * @Date 16/1/7 10:41
12 | */
13 | public class AggregateActor extends UntypedActor {
14 |
15 | /*最终的结果*/
16 | private Map finalReducedMap = new HashMap<>();
17 |
18 | @Override
19 | public void preStart() throws Exception {
20 | System.out.println("启动AggregateActor:"+Thread.currentThread().getName());
21 | }
22 |
23 | @Override
24 | public void onReceive(Object message) throws Exception {
25 | /*如果是Map,那么就进行reduce操作*/
26 | if (message instanceof Map) {
27 | Map reducedList = (Map) message;
28 | aggregateInMemoryReduce(reducedList);
29 | } else if (message instanceof String) {
30 | /*如果是String,那么就是打印结果*/
31 | if (((String) message).compareTo("DISPLAY_LIST") == 0) {
32 | //getSender().tell(finalReducedMap.toString());
33 | System.out.println(finalReducedMap.toString());
34 |
35 | }
36 | }else if (message instanceof Boolean) {
37 | /*向客户端发送已经reduce完成的信息*/
38 | getSender().tell(true,null);
39 | }
40 | }
41 |
42 | private void aggregateInMemoryReduce(Map reducedList) {
43 |
44 | for (String key : reducedList.keySet()) {
45 | /*最终的数量的累加*/
46 | if (finalReducedMap.containsKey(key)) {
47 | Integer count = reducedList.get(key) + finalReducedMap.get(key);
48 | finalReducedMap.put(key, count);
49 | } else {
50 | finalReducedMap.put(key, reducedList.get(key));
51 | }
52 |
53 | }
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo2/server/actor/MapActor.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo2.server.actor;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.List;
6 | import java.util.StringTokenizer;
7 |
8 | import akka.actor.ActorRef;
9 | import akka.actor.UntypedActor;
10 | import cn.sunxiang0918.akka.demo2.server.model.Result;
11 |
12 | /**
13 | * @author SUN
14 | * @version 1.0
15 | * @Date 16/1/7 10:33
16 | */
17 | public class MapActor extends UntypedActor {
18 |
19 | //停用词
20 | String[] STOP_WORDS = {"a", "about", "above", "above", "across", "after",
21 | "afterwards", "again", "against", "all", "almost", "alone",
22 | "along", "already", "also", "although", "always", "am", "among",
23 | "amongst", "amoungst", "amount", "an", "and", "another", "any",
24 | "anyhow", "anyone", "anything", "anyway", "anywhere", "are",
25 | "around", "as", "at", "back", "be", "became", "because", "become",
26 | "becomes", "becoming", "been", "before", "beforehand", "behind",
27 | "being", "below", "beside", "besides", "between", "beyond", "bill",
28 | "both", "bottom", "but", "by", "call", "can", "cannot", "cant",
29 | "co", "con", "could", "couldnt", "cry", "de", "describe", "detail",
30 | "do", "done", "down", "due", "during", "each", "eg", "eight",
31 | "either", "eleven", "else", "elsewhere", "empty", "enough", "etc",
32 | "even", "ever", "every", "everyone", "everything", "everywhere",
33 | "except", "few", "fifteen", "fify", "fill", "find", "fire",
34 | "first", "five", "for", "former", "formerly", "forty", "found",
35 | "four", "from", "front", "full", "further", "get", "give", "go",
36 | "had", "has", "hasnt", "have", "he", "hence", "her", "here",
37 | "hereafter", "hereby", "herein", "hereupon", "hers", "herself",
38 | "him", "himself", "his", "how", "however", "hundred", "ie", "if",
39 | "in", "inc", "indeed", "interest", "into", "is", "it", "its",
40 | "itself", "keep", "last", "latter", "latterly", "least", "less",
41 | "ltd", "made", "many", "may", "me", "meanwhile", "might", "mill",
42 | "mine", "more", "moreover", "most", "mostly", "move", "much",
43 | "must", "my", "myself", "name", "namely", "neither", "never",
44 | "nevertheless", "next", "nine", "no", "nobody", "none", "noone",
45 | "nor", "not", "nothing", "now", "nowhere", "of", "off", "often",
46 | "on", "once", "one", "only", "onto", "or", "other", "others",
47 | "otherwise", "our", "ours", "ourselves", "out", "over", "own",
48 | "part", "per", "perhaps", "please", "put", "rather", "re", "same",
49 | "see", "seem", "seemed", "seeming", "seems", "serious", "several",
50 | "she", "should", "show", "side", "since", "sincere", "six",
51 | "sixty", "so", "some", "somehow", "someone", "something",
52 | "sometime", "sometimes", "somewhere", "still", "such", "system",
53 | "take", "ten", "than", "that", "the", "their", "them",
54 | "themselves", "then", "thence", "there", "thereafter", "thereby",
55 | "therefore", "therein", "thereupon", "these", "they", "thickv",
56 | "thin", "third", "this", "those", "though", "three", "through",
57 | "throughout", "thru", "thus", "to", "together", "too", "top",
58 | "toward", "towards", "twelve", "twenty", "two", "un", "under",
59 | "until", "up", "upon", "us", "very", "via", "was", "we", "well",
60 | "were", "what", "whatever", "when", "whence", "whenever", "where",
61 | "whereafter", "whereas", "whereby", "wherein", "whereupon",
62 | "wherever", "whether", "which", "while", "whither", "who",
63 | "whoever", "whole", "whom", "whose", "why", "will", "with",
64 | "within", "without", "would", "yet", "you", "your", "yours",
65 | "yourself", "yourselves", "the"};
66 |
67 | List STOP_WORDS_LIST = Arrays.asList(STOP_WORDS);
68 |
69 | /*reduce聚合的Actor*/
70 | private ActorRef actor = null;
71 |
72 | public MapActor(ActorRef inReduceActor) {
73 | actor = inReduceActor;
74 | }
75 |
76 | @Override
77 | public void preStart() throws Exception {
78 | System.out.println("启动MapActor:"+Thread.currentThread().getName());
79 | }
80 |
81 | /**
82 | * 用于分词 计算单词的数量的
83 | * @param line
84 | * @return
85 | */
86 | private List evaluateExpression(String line) {
87 | List list = new ArrayList<>();
88 | /*字符串分词器*/
89 | StringTokenizer parser = new StringTokenizer(line);
90 | while (parser.hasMoreTokens()) {
91 | /*如果是,那么就判断是否是字母.然后把结果记录下来*/
92 | String word = parser.nextToken().toLowerCase();
93 | if (isAlpha(word) && !STOP_WORDS_LIST.contains(word)) {
94 | list.add(new Result(word, 1));
95 | }
96 | }
97 | return list;
98 | }
99 |
100 | /**
101 | * 判断是否是字母
102 | * @param s
103 | * @return
104 | */
105 | private boolean isAlpha(String s) {
106 | s = s.toUpperCase();
107 | for (int i = 0; i < s.length(); i++) {
108 | int c = (int) s.charAt(i);
109 | if (c < 65 || c > 90)
110 | return false;
111 | }
112 | return true;
113 | }
114 |
115 | @Override
116 | public void onReceive(Object message) throws Exception {
117 | if (message instanceof String) {
118 | String work = (String) message;
119 |
120 | if (work.equals("EOF")){
121 | /*表示已经结束了*/
122 | actor.tell(true,null);
123 | return;
124 | }
125 |
126 | // 计算这一行的单词情况
127 | List list = evaluateExpression(work);
128 |
129 | // 把这一行的单词情况发送给汇总的ReduceActor
130 | actor.tell(list, null);
131 | } else
132 | throw new IllegalArgumentException("Unknown message [" + message + "]");
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo2/server/actor/ReduceActor.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo2.server.actor;
2 |
3 | import java.util.List;
4 | import java.util.NavigableMap;
5 | import java.util.concurrent.ConcurrentSkipListMap;
6 |
7 | import akka.actor.ActorRef;
8 | import akka.actor.UntypedActor;
9 | import cn.sunxiang0918.akka.demo2.server.model.Result;
10 |
11 | /**
12 | * @author SUN
13 | * @version 1.0
14 | * @Date 16/1/7 10:38
15 | */
16 | public class ReduceActor extends UntypedActor {
17 |
18 | /*管道Actor*/
19 | private ActorRef actor = null;
20 |
21 | public ReduceActor(ActorRef inAggregateActor) {
22 | actor = inAggregateActor;
23 | }
24 |
25 | @Override
26 | public void preStart() throws Exception {
27 | System.out.println("启动ReduceActor:"+Thread.currentThread().getName());
28 | }
29 |
30 | @Override
31 | public void onReceive(Object message) throws Exception {
32 | if (message instanceof List) {
33 |
34 | /*强制转换结果*/
35 | List work = (List) message;
36 |
37 | // 第一次汇总单词表结果.
38 | NavigableMap reducedList = reduce(work);
39 |
40 | // 把这次汇总的结果发送给最终的结果聚合Actor
41 | actor.tell(reducedList, null);
42 |
43 | }else if (message instanceof Boolean) {
44 | //表示已经计算结束了
45 | // 把这次汇总的结果发送给最终的结果聚合Actor
46 | actor.tell(message, null);
47 | } else
48 | throw new IllegalArgumentException("Unknown message [" + message + "]");
49 | }
50 |
51 | /**
52 | * 聚合计算本次结果中各个单词的出现次数
53 | * @param list
54 | * @return
55 | */
56 | private NavigableMap reduce(List list) {
57 |
58 | NavigableMap reducedMap = new ConcurrentSkipListMap<>();
59 |
60 | for (Result result : list) {
61 | /*遍历结果,如果在这个小的结果中已经存在相同的单词了,那么数量+1,否则新建*/
62 | if (reducedMap.containsKey(result.getWord())) {
63 | Integer value = reducedMap.get(result.getWord());
64 | value++;
65 | reducedMap.put(result.getWord(), value);
66 | } else {
67 | reducedMap.put(result.getWord(), 1);
68 | }
69 | }
70 | return reducedMap;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo2/server/actor/WCMapReduceActor.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo2.server.actor;
2 |
3 | import akka.actor.ActorRef;
4 | import akka.actor.UntypedActor;
5 |
6 | /**
7 | * @author SUN
8 | * @version 1.0
9 | * @Date 16/1/7 10:30
10 | */
11 | public class WCMapReduceActor extends UntypedActor{
12 |
13 | private ActorRef mapRouter;
14 | private ActorRef aggregateActor;
15 |
16 | @Override
17 | public void preStart() throws Exception {
18 | System.out.println("启动WCMapReduceActor:"+Thread.currentThread().getName());
19 | }
20 |
21 | @Override
22 | public void onReceive(Object message) throws Exception {
23 | if (message instanceof String) {
24 | /*如果接收到的是显示结果的请求,那么就调用reduce的Actor*/
25 | if (((String) message).compareTo("DISPLAY_LIST") == 0) {
26 | System.out.println("Got Display Message");
27 | aggregateActor.tell(message, getSender());
28 | }if (message.equals("EOF")){
29 | //表示发送完毕
30 | aggregateActor.tell(true, getSender());
31 | }else {
32 | /*否则给map的Actor进行计算*/
33 | mapRouter.tell(message,null);
34 | }
35 | }
36 | }
37 |
38 | public WCMapReduceActor(ActorRef inAggregateActor, ActorRef inMapRouter) {
39 | mapRouter = inMapRouter;
40 | aggregateActor = inAggregateActor;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo2/server/model/Result.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo2.server.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * @author SUN
7 | * @version 1.0
8 | * @Date 16/1/7 10:33
9 | */
10 | public class Result implements Serializable {
11 |
12 | /**
13 | *
14 | */
15 | private static final long serialVersionUID = 5727560172917790458L;
16 | private String word; //单词
17 | private int no_of_instances; //数量
18 |
19 | public Result(String word, int no_of_instances) {
20 | this.setWord(word);
21 | this.setNoOfInstances(no_of_instances);
22 | }
23 |
24 | public void setWord(String word) {
25 | this.word = word;
26 | }
27 |
28 | public String getWord() {
29 | return word;
30 | }
31 |
32 | public void setNoOfInstances(int no_of_instances) {
33 | this.no_of_instances = no_of_instances;
34 | }
35 |
36 | public int getNoOfInstances() {
37 | return no_of_instances;
38 | }
39 |
40 | public String toString() {
41 | return word + ":" + no_of_instances;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo3/AkkaMain3.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo3;
2 |
3 | import akka.actor.ActorRef;
4 | import akka.actor.ActorSystem;
5 | import akka.actor.Props;
6 | import akka.routing.RoundRobinPool;
7 | import cn.sunxiang0918.akka.demo3.actor.JobControllerActor;
8 | import cn.sunxiang0918.akka.demo3.actor.WorkerActor;
9 |
10 | /**
11 | * @author SUN
12 | * @version 1.0
13 | * @Date 16/1/6 22:37
14 | */
15 | public class AkkaMain3 {
16 |
17 | static final int no_of_msgs = 10000;
18 |
19 | final int no_of_workers = 10;
20 |
21 | final ActorRef router;
22 |
23 | public AkkaMain3() {
24 | final int no_of_workers = 10000;
25 |
26 | ActorSystem system = ActorSystem.create("LoadGeneratorApp");
27 |
28 | final ActorRef appManager = system.actorOf(Props.create(JobControllerActor.class, no_of_msgs), "jobController");//启动jobController
29 |
30 | router = system.actorOf(Props.create(WorkerActor.class, appManager).withRouter(new RoundRobinPool(no_of_workers))); //启动带RoundRobinRouter的workerActor
31 |
32 | }
33 |
34 | public static void main(String[] args) throws Exception {
35 | new AkkaMain3().generateLoad();
36 | }
37 |
38 | private void generateLoad() {//开始产生1000万消息
39 | for (int i = no_of_msgs; i >= 0; i--) {
40 | router.tell("Job Id " + i + "# send", ActorRef.noSender());
41 | }
42 | System.out.println("All jobs sent successfully");
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo3/actor/JobControllerActor.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo3.actor;
2 |
3 | import akka.actor.UntypedActor;
4 |
5 | /**
6 | * @author SUN
7 | * @version 1.0
8 | * @Date 16/1/6 22:33
9 | */
10 | public class JobControllerActor extends UntypedActor{
11 |
12 | int count = 0;
13 | long startedTime = System.currentTimeMillis();
14 | int no_of_msgs = 0;
15 |
16 | public JobControllerActor(int no_of_msgs) {
17 | this.no_of_msgs = no_of_msgs;
18 | }
19 |
20 | @Override
21 | public void onReceive(Object message) throws Exception {
22 | if (message instanceof String){
23 | if (message.equals("DONE")){
24 | count++;
25 | if (count == no_of_msgs) {//计数到达1000万结束,统计时间
26 | long now = System.currentTimeMillis();
27 | System.out.println("All messages processed in "
28 | + (now - startedTime)+" millionseconds");
29 |
30 | System.out.println("Total Number of messages processed "
31 | + count);
32 | getContext().system().shutdown();
33 | }
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo3/actor/WorkerActor.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo3.actor;
2 |
3 | import org.apache.http.HttpResponse;
4 | import org.apache.http.client.methods.HttpPost;
5 | import org.apache.http.impl.client.DefaultHttpClient;
6 |
7 | import akka.actor.ActorRef;
8 | import akka.actor.UntypedActor;
9 |
10 | /**
11 | * @author SUN
12 | * @version 1.0
13 | * @Date 16/1/6 22:35
14 | */
15 | public class WorkerActor extends UntypedActor {
16 |
17 | private ActorRef jobController;//jobController是接受者
18 |
19 | @Override //接受到generateLoad的发送消息
20 | public void onReceive(Object message) throws Exception {
21 | // using scheduler to send the reply after 1000 milliseconds
22 | // getContext()
23 | // .system()
24 | // .scheduler()
25 | // .scheduleOnce(Duration.create(1000, TimeUnit.MILLISECONDS),jobController,"DONE",getContext()
26 | // .system().dispatcher(),ActorRef.noSender());
27 |
28 | //http://172.16.131.36:8081/api/media/task/media/info
29 |
30 | // System.out.println(Thread.currentThread().getName());
31 |
32 | DefaultHttpClient httpclient = new DefaultHttpClient();
33 |
34 | // 目标地址
35 | HttpPost httppost = new HttpPost(
36 | "http://172.16.131.36:8081/api/media/task/media/info");
37 |
38 | HttpResponse response = httpclient.execute(httppost);
39 |
40 | // System.out.println(response.getStatusLine().getStatusCode());
41 |
42 | httpclient.close();
43 |
44 | jobController.tell("DONE",ActorRef.noSender());
45 |
46 | }
47 |
48 | public WorkerActor(ActorRef inJobController) {
49 | jobController = inJobController;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/cn/sunxiang0918/akka/demo4/AkkaMain4.java:
--------------------------------------------------------------------------------
1 | package cn.sunxiang0918.akka.demo4;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Iterator;
5 | import java.util.concurrent.TimeUnit;
6 |
7 | import akka.actor.ActorSystem;
8 | import akka.actor.Props;
9 | import akka.dispatch.Futures;
10 | import akka.dispatch.Mapper;
11 | import akka.util.Timeout;
12 | import cn.sunxiang0918.akka.demo4.actor.ReceiveActor;
13 | import cn.sunxiang0918.akka.demo4.actor.ResultActor;
14 | import cn.sunxiang0918.akka.demo4.model.Result;
15 | import scala.concurrent.Future;
16 | import scala.concurrent.duration.Duration;
17 |
18 | import static akka.pattern.Patterns.ask;
19 | import static akka.pattern.Patterns.pipe;
20 |
21 | /**
22 | * @author SUN
23 | * @version 1.0
24 | * @Date 16/1/7 20:26
25 | */
26 | public class AkkaMain4 {
27 |
28 | public static void main(String[] args) throws Exception {
29 | final ActorSystem system = ActorSystem.create("demo4");
30 |
31 | //超时时间
32 | final Timeout t = new Timeout(Duration.create(5, TimeUnit.SECONDS));
33 |
34 | //异步反馈futures
35 | final ArrayList> futures = new ArrayList<>();
36 |
37 | futures.add(ask(system.actorOf(Props.create(ReceiveActor.class)), "request", 1000)); // using 1000ms timeout
38 | futures.add(ask(system.actorOf(Props.create(ReceiveActor.class)), "another request", t)); // using timeout from
39 |
40 | /*定义结果聚合管道*/
41 | final Future> aggregate = Futures.sequence(futures,
42 | system.dispatcher());
43 |
44 | /*对聚合的结果做map操作.*/
45 | final Future transformed = aggregate.map(
46 | new Mapper, Result>() {
47 | public Result apply(Iterable