Http://www.tuicool.com/articles/m2muui
The original http://2014.54chen.com/blog/2014/04/17/how-to-use-akka-in-java-3/ An example is also a classic example of Typesafe. Examples of services provided are the transmission of text. When the text is sent to the frontend node, it delegates the backend node, backend performs the transformation task, and returns the result to the original client. The new backend nodes and Frontend nodes can be dynamically added or subtracted on the cluster. Message
|
Public interface Transformationmessages {public
static class Transformationjob implements Serializable {
Private final String text;
//......
}
public static class Transformationresult implements Serializable {
private final String text;
//.....
}
public static class Jobfailed implements Serializable {
private final String reason;
Private final transformationjob job;
//....
}
public static final String backend_registration = "backendregistration";
} |
Backend processing Logic
|
public class Transformationbackend extends Untypedactor {Cluster Cluster = Cluster.get (GetContext (). System ()); @Override public void OnReceive (Object message) {if (instanceof transformationjob) {Transformatio
Njob 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); } void register (member member) {if (Member.hasrole ("Frontend")) GetContext (). Actorselection (Member.addre SS () + "/user/frontend"). Tell (Backend_registration, getself ()); }
} |
Backend subscribes to the cluster event, detects the Frontend node, and sends a message telling Fontend that it can be used. The frontend node receives the user's task and throws it to the registered backend node.
frontend node
|
public class Transformationfrontend extends Untypedactor {list<actorref> backends = new arraylist<actorref>
();
int jobcounter = 0; @Override public void OnReceive (Object message) {if (instanceof transformationjob) && backends.ise
Mpty ()) {Transformationjob job = (transformationjob) message;
Getsender (). Tell (New Jobfailed ("Service unavailable, try again later", job), Getsender ());
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); }
}
} |
Frontend uses the list to save the backend actor position, and when necessary, turn to backend. Getsender is the upstream of this message and is generally used to reply to messages. GetContext the context of this actor. GetContext (). Watch Deathwatch, the equivalent of watch who, who has any public action will tell me, including the hang of the sort. The difference between actorref.forward and tell and ask, the best performance is tell, go after the hair. Ask is to send out the future, to wait for the performance is a problem. Forward is used to forward messages from one actor to another actor, the original sender information is preserved and is useful for routing, load balancing, and backup.
Run TransformationappSAMPLE.CLUSTER.TRANSFORMATION.TRANSFORMATIONAPP starts with three backend 2551 2552 0 for a cluster and starts a fronend. Frontend receives a task every 5 seconds and receives the successful print code as follows:
|
System.scheduler (). Schedule (interval, interval, new Runnable () {public
void run () {Ask
(frontend,
new Transformationjob ("hello-" + counter.incrementandget ()),
timeout). onsuccess (New onsuccess<object> () { Public
void onsuccess (Object result) {
System.out.println (result);
}}
, EC);
}
, EC); |
Frontend node, when you receive a job, you will check to see if the backend registration number is available and forward the task if available.
|
public void OnReceive (Object message) {if (message instanceof transformationjob) && backends.isempty ()) {Transformationjob job = (Transform
ationjob) message;
Getsender (). Tell (New Jobfailed ("Service unavailable, try again later", job), Getsender ());
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); }
} |
There is a code in the backend as follows:
|
void register (member member) {
if (member.hasrole ("Frontend"))
GetContext (). Actorselection (Member.address ( ) + "/user/frontend"). Tell (
backend_registration, getself ());
|
Resolution: Backend subscribed to the Memberup event, so if there is Memberup in cluster, the above code will be executed. Actorselection is based on the address of lookup, return a actorselection, can be as local actor like tell.
CodeThis article mentions code in Https://github.com/54chen/akka_cluster_learn
Original articles such as reprint, please specify: Reproduced from the May Fourth Academy of Sciences [Http://www.54chen.com]