This slide shows you how to use Akka cluster in Java.
Source Code: https://github.com/jiayun/akka_samples
If you want to use the links in slide, please download the pdf file.
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);
}
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);
}
}
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());
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());
}
}