SlideShare a Scribd company logo
1 of 63
Download to read offline
#JCConf
Akka Cluster in Java
Jiayun Zhou
jiayun@gmail.com
Introduction
Akka
Concurrent & Distributed
Actor Model
http://blog.shiftehfar.org/?p=431
Scala
Java?
Scala is better
Java
Maven
Basic
pom.xml
<dependencies>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.11</artifactId>
<version>2.4.1</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>typesafe</id>
<name>Typesafe Repository</name>
<url>http://repo.typesafe.com/typesafe/releases/</url>
</repository>
</repositories>
Main.java
public static void main(String[] args) {
// akka.Main.main(new
String[]{HelloWorld.class.getName()});
ActorSystem system = ActorSystem.create("Hello");
ActorRef a =
system.actorOf(Props.create(HelloWorld.class), "helloWorld");
}
HelloWorld Actor
public class HelloWorld extends UntypedActor {
@Override
public void preStart() {
final ActorRef greeter =
getContext().actorOf(Props.create(Greeter.class), "greeter");
greeter.tell(Greeter.Msg.GREET, getSelf());
}
@Override
public void onReceive(Object msg) {
if (msg == Greeter.Msg.DONE) {
getContext().stop(getSelf());
} else
unhandled(msg);
}
}
Greeter Actor
public class Greeter extends UntypedActor {
public static enum Msg {
GREET, DONE;
}
@Override
public void onReceive(Object msg) {
if (msg == Msg.GREET) {
System.out.println("Hello World!");
getSender().tell(Msg.DONE, getSelf());
} else
unhandled(msg);
}
}
Sending message
• tell() – Fire and forget
• ask() – Send and receive
Avoid Ask
• https://www.safaribooksonline.com/library/view/effective-
akka/9781449360061/ch02.html#_avoiding_ask
• https://www.safaribooksonline.com/library/view/effective-
akka/9781449360061/ch03.html#_tell_don_8217_t_ask
Remoting
pom.xml
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-remote_2.11</artifactId>
<version>2.4.1</version>
</dependency>
Local application.conf
LocalSys {
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "127.0.0.1"
port = 2551
}
}
}
}
Remote application.conf
RemoteSys {
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "127.0.0.1"
port = 2552
}
}
}
}
Local Main
public static void main(String[] args) throws
Exception {
ActorSystem _system =
ActorSystem.create("LocalNodeApp",ConfigFactory
.load().getConfig("LocalSys"));
ActorRef localActor =
_system.actorOf(Props.create(LocalActor.class));
localActor.tell("Hello", null);
Thread.sleep(5000);
_system.shutdown();
}
Local Actor
ActorRef remoteActor;
@Override
public void preStart() {
//Get a reference to the remote actor
remoteActor = getContext().actorFor(
"akka.tcp://RemoteNodeApp@127.0.0.1:2552/user/remoteActor"
);
}
@Override
public void onReceive(Object message) throws Exception {
Future<Object> future = Patterns.ask(remoteActor,
message.toString(),
timeout);
String result = (String) Await.result(future,
timeout.duration());
log.info("Message received from Server -> {}", result);
}
Actor Path
akka.<protocol>://<actorsystemname>@<hos
tname>:<port>/<actor path>
• http://doc.akka.io/docs/akka/2.4.1/general/addressing.html
Remote Main
public static void main(String[] args) {
final ActorSystem system =
ActorSystem.create("RemoteNodeApp", ConfigFactory
.load().getConfig("RemoteSys"));
system.actorOf(Props.create(RemoteActor.class),
"remoteActor");
Runtime.getRuntime().addShutdownHook(new Thread()
{
@Override
public void run() {
system.shutdown();
}
});
}
Remote Actor
@Override
public void onReceive(Object message) throws
Exception {
if (message instanceof String) {
// Get reference to the message sender and
reply back
log.info("Message received -> {}", message);
getSender().tell(message + " got something",
null);
}
}
Router
Router Main
public static void main(String[] args) throws
InterruptedException {
ActorSystem _system =
ActorSystem.create("RemoteRouteeRouterExample",
ConfigFactory.load().getConfig("MyRouterExample"));
Address[] addresses = new Address[]{
new Address("akka.tcp", "RemoteNodeApp",
"10.211.55.6", 2552),
new Address("akka.tcp", "RemoteNodeApp",
"10.211.55.5", 2552)
};
ActorRef router = _system.actorOf(new RemoteRouterConfig(new
RoundRobinPool(5), addresses).props(
Props.create(RemoteActor.class)));
for (int i = 1; i <= 10; i++) {
// sends randomly to actors
router.tell("Hello " + Integer.toString(i), null);
}
_system.shutdown();
}
Cluster
pom.xml
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-cluster_2.11</artifactId>
<version>2.4.1</version>
</dependency>
application.conf
akka {
actor {
provider = "akka.cluster.ClusterActorRefProvider"
}
remote {
log-remote-lifecycle-events = off
netty.tcp {
hostname = "127.0.0.1"
port = 0
}
}
cluster {
seed-nodes = [
"akka.tcp://ClusterSystem@10.211.55.5:2552",
"akka.tcp://ClusterSystem@10.211.55.6:2552"]
auto-down-unreachable-after = 10s
}
}
Seed Nodes
Member States
Backend Main
public static void main(String[] args) {
// Override the configuration of the port when specified as
program argument
final String hostname = args.length > 0 ? args[0] : "127.0.0.1";
final String port = args.length > 1 ? args[1] : "0";
final Config config =
ConfigFactory.parseString("akka.remote.netty.tcp.hostname=" +
hostname).
withFallback(ConfigFactory.parseString("akka.remote.netty.tcp.port="
+ port)).
withFallback(ConfigFactory.parseString("akka.cluster.roles =
[backend]")).
withFallback(ConfigFactory.load());
ActorSystem system = ActorSystem.create("ClusterSystem", config);
system.actorOf(Props.create(TransformationBackend.class),
"backend");
}
Backend Actor - 1
Cluster cluster = Cluster.get(getContext().system());
//subscribe to cluster changes, MemberUp
@Override
public void preStart() {
cluster.subscribe(getSelf(), MemberUp.class);
}
//re-subscribe when restart
@Override
public void postStop() {
cluster.unsubscribe(getSelf());
}
void register(Member member) {
if (member.hasRole("frontend"))
getContext().actorSelection(member.address() +
"/user/frontend").tell(
BACKEND_REGISTRATION, getSelf());
}
Backend Actor - 2
@Override
public void onReceive(Object message) {
if (message instanceof TransformationJob) {
TransformationJob job = (TransformationJob) message;
getSender().tell(new
TransformationResult(job.getText().toUpperCase()),
getSelf());
} else if (message instanceof CurrentClusterState) {
CurrentClusterState state = (CurrentClusterState) message;
for (Member member : state.getMembers()) {
if (member.status().equals(MemberStatus.up())) {
register(member);
}
}
} else if (message instanceof MemberUp) {
MemberUp mUp = (MemberUp) message;
register(mUp.member());
} else {
unhandled(message);
}
}
Frontend Main - 1
final String hostname = args.length > 0 ? args[0] :
"127.0.0.1";
final String port = args.length > 1 ? args[1] : "0";
final Config config =
ConfigFactory.parseString("akka.remote.netty.tcp.host
name=" + hostname).
withFallback(ConfigFactory.parseString("akka.remote.n
etty.tcp.port=" + port)).
withFallback(ConfigFactory.parseString("akka.cluster.
roles = [frontend]")).
withFallback(ConfigFactory.load());
ActorSystem system =
ActorSystem.create("ClusterSystem", config);
Frontend Main - 2
final ActorRef frontend = system.actorOf(
Props.create(TransformationFrontend.class),
"frontend");
…
system.scheduler().schedule(interval, interval, new
Runnable() {
public void run() {
Patterns.ask(frontend,
new TransformationJob("hello-" +
counter.incrementAndGet()),
timeout).onSuccess(new OnSuccess<Object>()
{
public void onSuccess(Object result) {
System.out.println(result);
}
}, ec);
}
}, ec);
Frontend Actor - 1
List<ActorRef> backends = new ArrayList<ActorRef>();
int jobCounter = 0;
@Override
public void onReceive(Object message) {
if ((message instanceof TransformationJob) &&
backends.isEmpty()) {
TransformationJob job = (TransformationJob)
message;
getSender().tell(
new JobFailed("Service unavailable, try again
later", job),
getSender());
Frontend Actor - 2
} else if (message instanceof TransformationJob) {
TransformationJob job = (TransformationJob) message;
jobCounter++;
backends.get(jobCounter % backends.size())
.forward(job, getContext());
} else if (message.equals(BACKEND_REGISTRATION)) {
getContext().watch(getSender());
backends.add(getSender());
} else if (message instanceof Terminated) {
Terminated terminated = (Terminated) message;
backends.remove(terminated.getActor());
} else {
unhandled(message);
}
}
Run
java -cp .:./*
sample.cluster.transformation.TransformationBackendMa
in 10.211.55.5 2552
java -cp .:./*
sample.cluster.transformation.TransformationBackendMa
in 10.211.55.6 2552
java -cp .:./*
sample.cluster.transformation.TransformationFrontendM
ain 10.211.55.2 2552
Best Practices
• At least two seed nodes
• Use fixed port if possible
Something not mentioned
• Supervision
• Persistence
• …
ZooKeeper
3 ZooKeeper Servers
pom.xml
<dependency>
<groupId>com.sclasen</groupId>
<artifactId>akka-zk-cluster-seed_2.11</artifactId>
<version>0.1.2</version>
</dependency>
application.conf
akka {
loglevel = "DEBUG"
stdout-loglevel = "DEBUG"
actor {
provider = "akka.cluster.ClusterActorRefProvider"
}
remote {
log-remote-lifecycle-events = off
netty.tcp {
hostname = "127.0.0.1"
port = 0
}
}
cluster {
// seed-nodes = [
// "akka.tcp://ClusterSystem@10.211.55.5:2552",
// "akka.tcp://ClusterSystem@10.211.55.6:2552"]
auto-down-unreachable-after = 10s
}
}
reference.conf
akka.cluster.seed.zookeeper {
url = "10.211.55.2:2181,10.211.55.5:2181,10.211.55.6:2181"
path = "/akka/cluster/seed"
}
Join Cluster
ActorSystem system = ActorSystem.create("ClusterSystem", config);
new ZookeeperClusterSeed((ExtendedActorSystem)system).join();
Cluster & Router
factorial.conf - 1
include "application"
# //#min-nr-of-members
akka.cluster.min-nr-of-members = 3
# //#min-nr-of-members
# //#role-min-nr-of-members
akka.cluster.role {
frontend.min-nr-of-members = 1
backend.min-nr-of-members = 2
}
# //#role-min-nr-of-members
factorial.conf - 2
# //#adaptive-router
akka.actor.deployment {
/factorialFrontend/factorialBackendRouter = {
router = adaptive-group
# metrics-selector = heap
# metrics-selector = load
# metrics-selector = cpu
metrics-selector = mix
nr-of-instances = 100
routees.paths = ["/user/factorialBackend"]
cluster {
enabled = on
use-role = backend
allow-local-routees = off
}
}
}
# //#adaptive-router
Backend Main
final String port = args.length > 0 ? args[0] : "0";
final Config config =
ConfigFactory.parseString("akka.remote.netty.tcp.port=" +
port).
withFallback(ConfigFactory.parseString("akka.cluster.roles
= [backend]")).
withFallback(ConfigFactory.load("factorial"));
ActorSystem system = ActorSystem.create("ClusterSystem",
config);
new
ZookeeperClusterSeed((ExtendedActorSystem)system).join();
system.actorOf(Props.create(FactorialBackend.class),
"factorialBackend");
system.actorOf(Props.create(MetricsListener.class),
"metricsListener");
Backend Actor
Frontend Main
final int upToN = 200;
final Config config = ConfigFactory.parseString(
"akka.cluster.roles = [frontend]").withFallback(
ConfigFactory.load("factorial"));
final ActorSystem system =
ActorSystem.create("ClusterSystem", config);
new
ZookeeperClusterSeed((ExtendedActorSystem)system).join();
Cluster.get(system).registerOnMemberUp(new Runnable() {
@Override
public void run() {
system.actorOf(Props.create(FactorialFrontend.class, upToN,
true),
"factorialFrontend");
}
});
Frontend Actor
ActorRef backend =
getContext().actorOf(FromConfig.getInstance().props(),
"factorialBackendRouter");
…
void sendJobs() {
log.info("Starting batch of factorials up to
[{}]", upToN);
for (int n = 1; n <= upToN; n++) {
backend.tell(n, getSelf());
}
}
Resources
Java Sample Code
https://github.com/jiayun/
akka_samples
https://www.safaribooksonlin
e.com/search/?query=Akka&
highlight=true
Thanks

More Related Content

What's hot

The internet of (lego) trains
The internet of (lego) trainsThe internet of (lego) trains
The internet of (lego) trainsGrzegorz Duda
 
The dark side of Akka and the remedy - bp.scala meetup
The dark side of Akka and the remedy - bp.scala meetupThe dark side of Akka and the remedy - bp.scala meetup
The dark side of Akka and the remedy - bp.scala meetupkrivachy
 
Java Play Restful JPA
Java Play Restful JPAJava Play Restful JPA
Java Play Restful JPAFaren faren
 
Java Play RESTful ebean
Java Play RESTful ebeanJava Play RESTful ebean
Java Play RESTful ebeanFaren faren
 
2014-02-20 | Akka Concurrency (Vienna Scala User Group)
2014-02-20 | Akka Concurrency (Vienna Scala User Group)2014-02-20 | Akka Concurrency (Vienna Scala User Group)
2014-02-20 | Akka Concurrency (Vienna Scala User Group)Dominik Gruber
 
Google App Engine With Java And Groovy
Google App Engine With Java And GroovyGoogle App Engine With Java And Groovy
Google App Engine With Java And GroovyKen Kousen
 
Short intro to scala and the play framework
Short intro to scala and the play frameworkShort intro to scala and the play framework
Short intro to scala and the play frameworkFelipe
 
Akka Futures and Akka Remoting
Akka Futures  and Akka RemotingAkka Futures  and Akka Remoting
Akka Futures and Akka RemotingKnoldus Inc.
 
Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Oscar Renalias
 
Python WSGI introduction
Python WSGI introductionPython WSGI introduction
Python WSGI introductionAgeeleshwar K
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot CampTroy Miles
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignLightbend
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysManuel Bernhardt
 
Unit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSUnit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSKnoldus Inc.
 
A Brief Introduce to WSGI
A Brief Introduce to WSGIA Brief Introduce to WSGI
A Brief Introduce to WSGIMingli Yuan
 
Advanced task management with Celery
Advanced task management with CeleryAdvanced task management with Celery
Advanced task management with CeleryMahendra M
 

What's hot (20)

Actor Model Akka Framework
Actor Model Akka FrameworkActor Model Akka Framework
Actor Model Akka Framework
 
The internet of (lego) trains
The internet of (lego) trainsThe internet of (lego) trains
The internet of (lego) trains
 
Celery with python
Celery with pythonCelery with python
Celery with python
 
The dark side of Akka and the remedy - bp.scala meetup
The dark side of Akka and the remedy - bp.scala meetupThe dark side of Akka and the remedy - bp.scala meetup
The dark side of Akka and the remedy - bp.scala meetup
 
Java Play Restful JPA
Java Play Restful JPAJava Play Restful JPA
Java Play Restful JPA
 
Java Play RESTful ebean
Java Play RESTful ebeanJava Play RESTful ebean
Java Play RESTful ebean
 
2014-02-20 | Akka Concurrency (Vienna Scala User Group)
2014-02-20 | Akka Concurrency (Vienna Scala User Group)2014-02-20 | Akka Concurrency (Vienna Scala User Group)
2014-02-20 | Akka Concurrency (Vienna Scala User Group)
 
Google App Engine With Java And Groovy
Google App Engine With Java And GroovyGoogle App Engine With Java And Groovy
Google App Engine With Java And Groovy
 
Short intro to scala and the play framework
Short intro to scala and the play frameworkShort intro to scala and the play framework
Short intro to scala and the play framework
 
Akka Futures and Akka Remoting
Akka Futures  and Akka RemotingAkka Futures  and Akka Remoting
Akka Futures and Akka Remoting
 
Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0
 
Python WSGI introduction
Python WSGI introductionPython WSGI introduction
Python WSGI introduction
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System Design
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDays
 
Unit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSUnit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJS
 
A Brief Introduce to WSGI
A Brief Introduce to WSGIA Brief Introduce to WSGI
A Brief Introduce to WSGI
 
Full Stack Unit Testing
Full Stack Unit TestingFull Stack Unit Testing
Full Stack Unit Testing
 
Django Celery
Django Celery Django Celery
Django Celery
 
Advanced task management with Celery
Advanced task management with CeleryAdvanced task management with Celery
Advanced task management with Celery
 

Viewers also liked

Akka Cluster in Production
Akka Cluster in ProductionAkka Cluster in Production
Akka Cluster in Productionbilyushonak
 
Slides - Intro to Akka.Cluster
Slides - Intro to Akka.ClusterSlides - Intro to Akka.Cluster
Slides - Intro to Akka.Clusterpetabridge
 
Akka cluster overview at 010dev
Akka cluster overview at 010devAkka cluster overview at 010dev
Akka cluster overview at 010devRoland Kuhn
 
Introduction to Akka
Introduction to AkkaIntroduction to Akka
Introduction to AkkaJohan Andrén
 
Developing distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterDeveloping distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterKonstantin Tsykulenko
 
Akka Cluster and Auto-scaling
Akka Cluster and Auto-scalingAkka Cluster and Auto-scaling
Akka Cluster and Auto-scalingIkuo Matsumura
 
Introduction to Actor Model and Akka
Introduction to Actor Model and AkkaIntroduction to Actor Model and Akka
Introduction to Actor Model and AkkaYung-Lin Ho
 
Akka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutesAkka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutesKonrad Malawski
 
The Actor Model - Towards Better Concurrency
The Actor Model - Towards Better ConcurrencyThe Actor Model - Towards Better Concurrency
The Actor Model - Towards Better ConcurrencyDror Bereznitsky
 

Viewers also liked (13)

Ionic2
Ionic2Ionic2
Ionic2
 
Akka Cluster in Production
Akka Cluster in ProductionAkka Cluster in Production
Akka Cluster in Production
 
Slides - Intro to Akka.Cluster
Slides - Intro to Akka.ClusterSlides - Intro to Akka.Cluster
Slides - Intro to Akka.Cluster
 
Akka cluster overview at 010dev
Akka cluster overview at 010devAkka cluster overview at 010dev
Akka cluster overview at 010dev
 
Introduction to Akka
Introduction to AkkaIntroduction to Akka
Introduction to Akka
 
Akka - A Brief Intro
Akka - A Brief IntroAkka - A Brief Intro
Akka - A Brief Intro
 
Developing distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterDeveloping distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka Cluster
 
Introduction to the Actor Model
Introduction to the Actor ModelIntroduction to the Actor Model
Introduction to the Actor Model
 
Akka Cluster and Auto-scaling
Akka Cluster and Auto-scalingAkka Cluster and Auto-scaling
Akka Cluster and Auto-scaling
 
Introduction to Actor Model and Akka
Introduction to Actor Model and AkkaIntroduction to Actor Model and Akka
Introduction to Actor Model and Akka
 
Introducing Akka
Introducing AkkaIntroducing Akka
Introducing Akka
 
Akka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutesAkka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutes
 
The Actor Model - Towards Better Concurrency
The Actor Model - Towards Better ConcurrencyThe Actor Model - Towards Better Concurrency
The Actor Model - Towards Better Concurrency
 

Similar to Akka Cluster in Java - JCConf 2015

Next generation message driven systems with Akka
Next generation message driven systems with AkkaNext generation message driven systems with Akka
Next generation message driven systems with AkkaJohan Andrén
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVMRafael Winterhalter
 
Painless Persistence with Realm
Painless Persistence with RealmPainless Persistence with Realm
Painless Persistence with RealmChristian Melchior
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js frameworkBen Lin
 
Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)aragozin
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6Dmitry Soshnikov
 
Threads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSThreads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSTechWell
 
Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lispelliando dias
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleRaimonds Simanovskis
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupHenrik Engström
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays
 
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 202010 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020Matt Raible
 
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen ChinHacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chinjaxconf
 

Similar to Akka Cluster in Java - JCConf 2015 (20)

Next generation message driven systems with Akka
Next generation message driven systems with AkkaNext generation message driven systems with Akka
Next generation message driven systems with Akka
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVM
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
What is new in Java 8
What is new in Java 8What is new in Java 8
What is new in Java 8
 
Painless Persistence with Realm
Painless Persistence with RealmPainless Persistence with Realm
Painless Persistence with Realm
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)Virtualizing Java in Java (jug.ru)
Virtualizing Java in Java (jug.ru)
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
 
Threads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSThreads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOS
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lisp
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
 
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 202010 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
 
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen ChinHacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
Hacking JavaFX with Groovy, Clojure, Scala, and Visage: Stephen Chin
 

More from Jiayun Zhou

More from Jiayun Zhou (6)

Spring Initializr JCConf 2018
Spring Initializr JCConf 2018Spring Initializr JCConf 2018
Spring Initializr JCConf 2018
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring & Hibernate
Spring & HibernateSpring & Hibernate
Spring & Hibernate
 
Python Style Guide
Python Style GuidePython Style Guide
Python Style Guide
 
Python3
Python3Python3
Python3
 
Refactoring
RefactoringRefactoring
Refactoring
 

Recently uploaded

Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 

Recently uploaded (20)

Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 

Akka Cluster in Java - JCConf 2015

  • 1. #JCConf Akka Cluster in Java Jiayun Zhou jiayun@gmail.com
  • 10. Java
  • 11.
  • 12. Maven
  • 13. Basic
  • 15. Main.java public static void main(String[] args) { // akka.Main.main(new String[]{HelloWorld.class.getName()}); ActorSystem system = ActorSystem.create("Hello"); ActorRef a = system.actorOf(Props.create(HelloWorld.class), "helloWorld"); }
  • 16. HelloWorld Actor public class HelloWorld extends UntypedActor { @Override public void preStart() { final ActorRef greeter = getContext().actorOf(Props.create(Greeter.class), "greeter"); greeter.tell(Greeter.Msg.GREET, getSelf()); } @Override public void onReceive(Object msg) { if (msg == Greeter.Msg.DONE) { getContext().stop(getSelf()); } else unhandled(msg); } }
  • 17. Greeter Actor public class Greeter extends UntypedActor { public static enum Msg { GREET, DONE; } @Override public void onReceive(Object msg) { if (msg == Msg.GREET) { System.out.println("Hello World!"); getSender().tell(Msg.DONE, getSelf()); } else unhandled(msg); } }
  • 18. Sending message • tell() – Fire and forget • ask() – Send and receive
  • 19. Avoid Ask • https://www.safaribooksonline.com/library/view/effective- akka/9781449360061/ch02.html#_avoiding_ask • https://www.safaribooksonline.com/library/view/effective- akka/9781449360061/ch03.html#_tell_don_8217_t_ask
  • 22. Local application.conf LocalSys { akka { actor { provider = "akka.remote.RemoteActorRefProvider" } remote { enabled-transports = ["akka.remote.netty.tcp"] netty.tcp { hostname = "127.0.0.1" port = 2551 } } } }
  • 23. Remote application.conf RemoteSys { akka { actor { provider = "akka.remote.RemoteActorRefProvider" } remote { enabled-transports = ["akka.remote.netty.tcp"] netty.tcp { hostname = "127.0.0.1" port = 2552 } } } }
  • 24. Local Main public static void main(String[] args) throws Exception { ActorSystem _system = ActorSystem.create("LocalNodeApp",ConfigFactory .load().getConfig("LocalSys")); ActorRef localActor = _system.actorOf(Props.create(LocalActor.class)); localActor.tell("Hello", null); Thread.sleep(5000); _system.shutdown(); }
  • 25. Local Actor ActorRef remoteActor; @Override public void preStart() { //Get a reference to the remote actor remoteActor = getContext().actorFor( "akka.tcp://RemoteNodeApp@127.0.0.1:2552/user/remoteActor" ); } @Override public void onReceive(Object message) throws Exception { Future<Object> future = Patterns.ask(remoteActor, message.toString(), timeout); String result = (String) Await.result(future, timeout.duration()); log.info("Message received from Server -> {}", result); }
  • 26. Actor Path akka.<protocol>://<actorsystemname>@<hos tname>:<port>/<actor path> • http://doc.akka.io/docs/akka/2.4.1/general/addressing.html
  • 27. Remote Main public static void main(String[] args) { final ActorSystem system = ActorSystem.create("RemoteNodeApp", ConfigFactory .load().getConfig("RemoteSys")); system.actorOf(Props.create(RemoteActor.class), "remoteActor"); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { system.shutdown(); } }); }
  • 28. Remote Actor @Override public void onReceive(Object message) throws Exception { if (message instanceof String) { // Get reference to the message sender and reply back log.info("Message received -> {}", message); getSender().tell(message + " got something", null); } }
  • 30. Router Main public static void main(String[] args) throws InterruptedException { ActorSystem _system = ActorSystem.create("RemoteRouteeRouterExample", ConfigFactory.load().getConfig("MyRouterExample")); Address[] addresses = new Address[]{ new Address("akka.tcp", "RemoteNodeApp", "10.211.55.6", 2552), new Address("akka.tcp", "RemoteNodeApp", "10.211.55.5", 2552) }; ActorRef router = _system.actorOf(new RemoteRouterConfig(new RoundRobinPool(5), addresses).props( Props.create(RemoteActor.class))); for (int i = 1; i <= 10; i++) { // sends randomly to actors router.tell("Hello " + Integer.toString(i), null); } _system.shutdown(); }
  • 33. application.conf akka { actor { provider = "akka.cluster.ClusterActorRefProvider" } remote { log-remote-lifecycle-events = off netty.tcp { hostname = "127.0.0.1" port = 0 } } cluster { seed-nodes = [ "akka.tcp://ClusterSystem@10.211.55.5:2552", "akka.tcp://ClusterSystem@10.211.55.6:2552"] auto-down-unreachable-after = 10s } }
  • 36. Backend Main public static void main(String[] args) { // Override the configuration of the port when specified as program argument final String hostname = args.length > 0 ? args[0] : "127.0.0.1"; final String port = args.length > 1 ? args[1] : "0"; final Config config = ConfigFactory.parseString("akka.remote.netty.tcp.hostname=" + hostname). withFallback(ConfigFactory.parseString("akka.remote.netty.tcp.port=" + port)). withFallback(ConfigFactory.parseString("akka.cluster.roles = [backend]")). withFallback(ConfigFactory.load()); ActorSystem system = ActorSystem.create("ClusterSystem", config); system.actorOf(Props.create(TransformationBackend.class), "backend"); }
  • 37. Backend Actor - 1 Cluster cluster = Cluster.get(getContext().system()); //subscribe to cluster changes, MemberUp @Override public void preStart() { cluster.subscribe(getSelf(), MemberUp.class); } //re-subscribe when restart @Override public void postStop() { cluster.unsubscribe(getSelf()); } void register(Member member) { if (member.hasRole("frontend")) getContext().actorSelection(member.address() + "/user/frontend").tell( BACKEND_REGISTRATION, getSelf()); }
  • 38. Backend Actor - 2 @Override public void onReceive(Object message) { if (message instanceof TransformationJob) { TransformationJob job = (TransformationJob) message; getSender().tell(new TransformationResult(job.getText().toUpperCase()), getSelf()); } else if (message instanceof CurrentClusterState) { CurrentClusterState state = (CurrentClusterState) message; for (Member member : state.getMembers()) { if (member.status().equals(MemberStatus.up())) { register(member); } } } else if (message instanceof MemberUp) { MemberUp mUp = (MemberUp) message; register(mUp.member()); } else { unhandled(message); } }
  • 39. Frontend Main - 1 final String hostname = args.length > 0 ? args[0] : "127.0.0.1"; final String port = args.length > 1 ? args[1] : "0"; final Config config = ConfigFactory.parseString("akka.remote.netty.tcp.host name=" + hostname). withFallback(ConfigFactory.parseString("akka.remote.n etty.tcp.port=" + port)). withFallback(ConfigFactory.parseString("akka.cluster. roles = [frontend]")). withFallback(ConfigFactory.load()); ActorSystem system = ActorSystem.create("ClusterSystem", config);
  • 40. Frontend Main - 2 final ActorRef frontend = system.actorOf( Props.create(TransformationFrontend.class), "frontend"); … system.scheduler().schedule(interval, interval, new Runnable() { public void run() { Patterns.ask(frontend, new TransformationJob("hello-" + counter.incrementAndGet()), timeout).onSuccess(new OnSuccess<Object>() { public void onSuccess(Object result) { System.out.println(result); } }, ec); } }, ec);
  • 41. Frontend Actor - 1 List<ActorRef> backends = new ArrayList<ActorRef>(); int jobCounter = 0; @Override public void onReceive(Object message) { if ((message instanceof TransformationJob) && backends.isEmpty()) { TransformationJob job = (TransformationJob) message; getSender().tell( new JobFailed("Service unavailable, try again later", job), getSender());
  • 42. Frontend Actor - 2 } else if (message instanceof TransformationJob) { TransformationJob job = (TransformationJob) message; jobCounter++; backends.get(jobCounter % backends.size()) .forward(job, getContext()); } else if (message.equals(BACKEND_REGISTRATION)) { getContext().watch(getSender()); backends.add(getSender()); } else if (message instanceof Terminated) { Terminated terminated = (Terminated) message; backends.remove(terminated.getActor()); } else { unhandled(message); } }
  • 43. Run java -cp .:./* sample.cluster.transformation.TransformationBackendMa in 10.211.55.5 2552 java -cp .:./* sample.cluster.transformation.TransformationBackendMa in 10.211.55.6 2552 java -cp .:./* sample.cluster.transformation.TransformationFrontendM ain 10.211.55.2 2552
  • 44. Best Practices • At least two seed nodes • Use fixed port if possible
  • 45. Something not mentioned • Supervision • Persistence • …
  • 49. application.conf akka { loglevel = "DEBUG" stdout-loglevel = "DEBUG" actor { provider = "akka.cluster.ClusterActorRefProvider" } remote { log-remote-lifecycle-events = off netty.tcp { hostname = "127.0.0.1" port = 0 } } cluster { // seed-nodes = [ // "akka.tcp://ClusterSystem@10.211.55.5:2552", // "akka.tcp://ClusterSystem@10.211.55.6:2552"] auto-down-unreachable-after = 10s } }
  • 50. reference.conf akka.cluster.seed.zookeeper { url = "10.211.55.2:2181,10.211.55.5:2181,10.211.55.6:2181" path = "/akka/cluster/seed" }
  • 51. Join Cluster ActorSystem system = ActorSystem.create("ClusterSystem", config); new ZookeeperClusterSeed((ExtendedActorSystem)system).join();
  • 53. factorial.conf - 1 include "application" # //#min-nr-of-members akka.cluster.min-nr-of-members = 3 # //#min-nr-of-members # //#role-min-nr-of-members akka.cluster.role { frontend.min-nr-of-members = 1 backend.min-nr-of-members = 2 } # //#role-min-nr-of-members
  • 54. factorial.conf - 2 # //#adaptive-router akka.actor.deployment { /factorialFrontend/factorialBackendRouter = { router = adaptive-group # metrics-selector = heap # metrics-selector = load # metrics-selector = cpu metrics-selector = mix nr-of-instances = 100 routees.paths = ["/user/factorialBackend"] cluster { enabled = on use-role = backend allow-local-routees = off } } } # //#adaptive-router
  • 55. Backend Main final String port = args.length > 0 ? args[0] : "0"; final Config config = ConfigFactory.parseString("akka.remote.netty.tcp.port=" + port). withFallback(ConfigFactory.parseString("akka.cluster.roles = [backend]")). withFallback(ConfigFactory.load("factorial")); ActorSystem system = ActorSystem.create("ClusterSystem", config); new ZookeeperClusterSeed((ExtendedActorSystem)system).join(); system.actorOf(Props.create(FactorialBackend.class), "factorialBackend"); system.actorOf(Props.create(MetricsListener.class), "metricsListener");
  • 57. Frontend Main final int upToN = 200; final Config config = ConfigFactory.parseString( "akka.cluster.roles = [frontend]").withFallback( ConfigFactory.load("factorial")); final ActorSystem system = ActorSystem.create("ClusterSystem", config); new ZookeeperClusterSeed((ExtendedActorSystem)system).join(); Cluster.get(system).registerOnMemberUp(new Runnable() { @Override public void run() { system.actorOf(Props.create(FactorialFrontend.class, upToN, true), "factorialFrontend"); } });
  • 58. Frontend Actor ActorRef backend = getContext().actorOf(FromConfig.getInstance().props(), "factorialBackendRouter"); … void sendJobs() { log.info("Starting batch of factorials up to [{}]", upToN); for (int n = 1; n <= upToN; n++) { backend.tell(n, getSelf()); } }