Download - Akka Cluster in Java - JCConf 2015
![Page 2: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/2.jpg)
Introduction
![Page 3: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/3.jpg)
Akka
![Page 4: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/4.jpg)
Concurrent & Distributed
![Page 5: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/5.jpg)
Actor Model
![Page 6: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/6.jpg)
http://blog.shiftehfar.org/?p=431
![Page 7: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/7.jpg)
Scala
![Page 8: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/8.jpg)
Java?
![Page 9: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/9.jpg)
Scala is better
![Page 10: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/10.jpg)
Java
![Page 11: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/11.jpg)
![Page 12: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/12.jpg)
Maven
![Page 13: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/13.jpg)
Basic
![Page 14: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/14.jpg)
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>
![Page 15: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/15.jpg)
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");}
![Page 16: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/16.jpg)
HelloWorld Actor
public class HelloWorld extends UntypedActor {
@Overridepublic void preStart() {
final ActorRef greeter = getContext().actorOf(Props.create(Greeter.class), "greeter");
greeter.tell(Greeter.Msg.GREET, getSelf());}
@Overridepublic void onReceive(Object msg) {
if (msg == Greeter.Msg.DONE) {getContext().stop(getSelf());
} elseunhandled(msg);
}}
![Page 17: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/17.jpg)
Greeter Actor
public class Greeter extends UntypedActor {
public static enum Msg {GREET, DONE;
}
@Overridepublic void onReceive(Object msg) {
if (msg == Msg.GREET) {System.out.println("Hello World!");getSender().tell(Msg.DONE, getSelf());
} elseunhandled(msg);
}
}
![Page 18: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/18.jpg)
Sending message
• tell() – Fire and forget• ask() – Send and receive
![Page 19: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/19.jpg)
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
![Page 20: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/20.jpg)
Remoting
![Page 21: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/21.jpg)
pom.xml
<dependency><groupId>com.typesafe.akka</groupId><artifactId>akka-remote_2.11</artifactId><version>2.4.1</version>
</dependency>
![Page 22: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/22.jpg)
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
}}
}}
![Page 23: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/23.jpg)
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
}}
}}
![Page 24: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/24.jpg)
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();
}
![Page 25: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/25.jpg)
Local Actor
ActorRef remoteActor;
@Overridepublic void preStart() {
//Get a reference to the remote actorremoteActor = getContext().actorFor(
"akka.tcp://[email protected]:2552/user/remoteActor");}
@Overridepublic 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);
}
![Page 26: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/26.jpg)
Actor Path
akka.<protocol>://<actorsystemname>@<hostname>:<port>/<actor path>
• http://doc.akka.io/docs/akka/2.4.1/general/addressing.html
![Page 27: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/27.jpg)
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() {
@Overridepublic void run() {
system.shutdown();}
});}
![Page 28: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/28.jpg)
Remote Actor
@Overridepublic void onReceive(Object message) throws Exception {
if (message instanceof String) {// Get reference to the message sender and
reply backlog.info("Message received -> {}", message);getSender().tell(message + " got something",
null);}
}
![Page 29: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/29.jpg)
Router
![Page 30: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/30.jpg)
Router Mainpublic 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 actorsrouter.tell("Hello " + Integer.toString(i), null);
}_system.shutdown();
}
![Page 31: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/31.jpg)
Cluster
![Page 32: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/32.jpg)
pom.xml
<dependency><groupId>com.typesafe.akka</groupId><artifactId>akka-cluster_2.11</artifactId><version>2.4.1</version>
</dependency>
![Page 33: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/33.jpg)
application.conf
akka {actor {provider = "akka.cluster.ClusterActorRefProvider"
}remote {log-remote-lifecycle-events = offnetty.tcp {hostname = "127.0.0.1"port = 0
}}
cluster {seed-nodes = ["akka.tcp://[email protected]:2552","akka.tcp://[email protected]:2552"]
auto-down-unreachable-after = 10s}
}
![Page 34: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/34.jpg)
Seed Nodes
![Page 35: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/35.jpg)
Member States
![Page 36: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/36.jpg)
Backend Mainpublic 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");
}
![Page 37: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/37.jpg)
Backend Actor - 1
Cluster cluster = Cluster.get(getContext().system());
//subscribe to cluster changes, MemberUp@Overridepublic void preStart() {cluster.subscribe(getSelf(), MemberUp.class);
}
//re-subscribe when restart@Overridepublic void postStop() {cluster.unsubscribe(getSelf());
}
void register(Member member) {if (member.hasRole("frontend"))getContext().actorSelection(member.address() +
"/user/frontend").tell(BACKEND_REGISTRATION, getSelf());
}
![Page 38: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/38.jpg)
Backend Actor - 2@Overridepublic 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);
}}
![Page 39: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/39.jpg)
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.hostname=" + hostname).
withFallback(ConfigFactory.parseString("akka.remote.netty.tcp.port=" + port)).
withFallback(ConfigFactory.parseString("akka.cluster.roles = [frontend]")).
withFallback(ConfigFactory.load());
ActorSystem system = ActorSystem.create("ClusterSystem", config);
![Page 40: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/40.jpg)
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);
![Page 41: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/41.jpg)
Frontend Actor - 1
List<ActorRef> backends = new ArrayList<ActorRef>();int jobCounter = 0;
@Overridepublic 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());
![Page 42: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/42.jpg)
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);
}}
![Page 43: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/43.jpg)
Run
java -cp .:./* sample.cluster.transformation.TransformationBackendMain 10.211.55.5 2552
java -cp .:./* sample.cluster.transformation.TransformationBackendMain 10.211.55.6 2552
java -cp .:./* sample.cluster.transformation.TransformationFrontendMain 10.211.55.2 2552
![Page 44: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/44.jpg)
Best Practices
• At least two seed nodes• Use fixed port if possible
![Page 45: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/45.jpg)
Something not mentioned
• Supervision• Persistence• …
![Page 46: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/46.jpg)
ZooKeeper
![Page 47: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/47.jpg)
3 ZooKeeper Servers
![Page 48: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/48.jpg)
pom.xml
<dependency><groupId>com.sclasen</groupId><artifactId>akka-zk-cluster-seed_2.11</artifactId><version>0.1.2</version>
</dependency>
![Page 49: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/49.jpg)
application.conf
akka {loglevel = "DEBUG"stdout-loglevel = "DEBUG"actor {provider = "akka.cluster.ClusterActorRefProvider"
}remote {log-remote-lifecycle-events = offnetty.tcp {hostname = "127.0.0.1"port = 0
}}
cluster {// seed-nodes = [// "akka.tcp://[email protected]:2552",// "akka.tcp://[email protected]:2552"]
auto-down-unreachable-after = 10s}
}
![Page 50: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/50.jpg)
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"
}
![Page 51: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/51.jpg)
Join Cluster
ActorSystem system = ActorSystem.create("ClusterSystem", config);new ZookeeperClusterSeed((ExtendedActorSystem)system).join();
![Page 52: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/52.jpg)
Cluster & Router
![Page 53: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/53.jpg)
factorial.conf - 1
include "application"
# //#min-nr-of-membersakka.cluster.min-nr-of-members = 3# //#min-nr-of-members
# //#role-min-nr-of-membersakka.cluster.role {frontend.min-nr-of-members = 1backend.min-nr-of-members = 2
}# //#role-min-nr-of-members
![Page 54: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/54.jpg)
factorial.conf - 2
# //#adaptive-routerakka.actor.deployment {/factorialFrontend/factorialBackendRouter = {
router = adaptive-group# metrics-selector = heap# metrics-selector = load# metrics-selector = cpumetrics-selector = mixnr-of-instances = 100routees.paths = ["/user/factorialBackend"]cluster {enabled = onuse-role = backendallow-local-routees = off
}}
}# //#adaptive-router
![Page 55: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/55.jpg)
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");
![Page 56: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/56.jpg)
Backend Actor
![Page 57: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/57.jpg)
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() {@Overridepublic void run() {
system.actorOf(Props.create(FactorialFrontend.class, upToN, true),
"factorialFrontend");}
});
![Page 58: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/58.jpg)
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());}
}
![Page 59: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/59.jpg)
Resources
![Page 60: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/60.jpg)
Java Sample Code
![Page 61: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/61.jpg)
https://github.com/jiayun/akka_samples
![Page 62: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/62.jpg)
https://www.safaribooksonline.com/search/?query=Akka&
highlight=true
![Page 63: Akka Cluster in Java - JCConf 2015](https://reader034.vdocuments.us/reader034/viewer/2022052318/58729f5d1a28ab07208b5673/html5/thumbnails/63.jpg)
Thanks