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

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
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 

Recently uploaded (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
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 

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()); } }