WIP cluster docs

This commit is contained in:
Patrik Nordwall 2012-08-16 14:48:15 +02:00
parent 846b8543fb
commit 331cd7fca3
6 changed files with 282 additions and 1 deletions

View file

@ -0,0 +1,84 @@
.. _cluster_usage:
#########
Cluster
#########
.. note:: *This document describes how to use the features implemented so far of the
new clustering coming in Akka Coltrane and is not available in the latest stable release.
The API might change before it is released.
For introduction to the Akka Cluster concepts please see
Preparing your ActorSystem for Clustering
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The Akka cluster is a separate jar file. Make sure that you have the following dependency in your project::
"com.typesafe.akka" % "akka-cluster" % "2.1-SNAPSHOT"
It can be difficult to find the correct versions and repositories at the moment. The following sbt 0.11.3 build
file illustrates what to use with Scala 2.10.0-M6 and Akka 2.1-SNAPSHOT
import sbt._
import sbt.Keys._
object ProjectBuild extends Build {
lazy val root = Project(
id = "root",
base = file("."),
settings = Project.defaultSettings ++ Seq(
name := "Akka Cluster Example",
organization := "org.test",
version := "0.1-SNAPSHOT",
scalaVersion := "2.10.0-M6",
resolvers += "Sonatype Releases Repo" at "https://oss.sonatype.org/content/repositories/releases/",
resolvers += "Sonatype Snapshot Repo" at "https://oss.sonatype.org/content/repositories/snapshots/",
resolvers += "Typesafe Releases" at "http://repo.typesafe.com/typesafe/releases",
resolvers += "Typesafe Snapshots" at "http://repo.typesafe.com/typesafe/snapshots/",
libraryDependencies ++= Seq(
"com.typesafe.akka" % "akka-cluster" % "2.1-20120816-000904",
"com.typesafe.akka" % "akka-testkit" % "2.1-20120816-000904" % "test",
"junit" % "junit" % "4.5" % "test",
"org.scalatest" %% "scalatest" % "1.9-2.10.0-M6-B2" % "test")
)
)
}
Pick a timestamped Akka version from `<http://repo.typesafe.com/typesafe/snapshots/com/typesafe/akka/akka-cluster/>`_.
To enable cluster capabilities in your Akka project you should, at a minimum, add the :ref:`remoting-scala`
settings and the ``cluster seed-nodes`` to your ``application.conf`` file:
.. literalinclude:: ../../akka-samples/akka-sample-remote/src/main/resources/common.conf
:language: none
The seed nodes are configured contact points for inital join of the cluster.
When a new node is started started it sends a message to all seed nodes and
then sends join command to the one that answers first.
A Simple Cluster Example
^^^^^^^^^^^^^^^^^^^^^^^^
Configuration
^^^^^^^^^^^^^
There are lots of more properties that are related to clustering in Akka. We refer to the following
reference file for more information:
.. literalinclude:: ../../akka-cluster/src/main/resources/reference.conf
:language: none

View file

@ -5,3 +5,4 @@ Cluster
:maxdepth: 2
cluster
cluster-usage

View file

@ -0,0 +1,143 @@
REMOTE CALCULATOR
=================
Requirements
------------
To build and run remote calculator you need [Simple Build Tool][sbt] (sbt).
The Sample Explained
--------------------
In order to showcase the remote capabilities of Akka 2.0 we thought a remote calculator could do the trick.
There are two implementations of the sample; one in Scala and one in Java.
The explanation below is for Scala, but everything is similar in Java except that the class names begin with a ``J``,
e.g. ``JCalcApp`` instead of ``CalcApp``, and that the Java classes reside in another package structure.
There are three actor systems used in the sample:
* CalculatorApplication : the actor system performing the number crunching
* LookupApplication : illustrates how to look up an actor on a remote node and and how communicate with that actor
* CreationApplication : illustrates how to create an actor on a remote node and how to communicate with that actor
The CalculatorApplication contains an actor, SimpleCalculatorActor, which can handle simple math operations such as
addition and subtraction. This actor is looked up and used from the LookupApplication.
The CreationApplication wants to use more "advanced" mathematical operations, such as multiplication and division,
but as the CalculatorApplication does not have any actor that can perform those type of calculations the
CreationApplication has to remote deploy an actor that can (which in our case is AdvancedCalculatorActor).
So this actor is deployed, over the network, onto the CalculatorApplication actor system and thereafter the
CreationApplication will send messages to it.
It is important to point out that as the actor system run on different ports it is possible to run all three in parallel.
See the next section for more information of how to run the sample application.
Running
-------
In order to run all three actor systems you have to start SBT in three different terminal windows.
We start off by running the CalculatorApplication:
First type 'sbt' to start SBT interactively, the run 'update' and 'run':
> cd $AKKA_HOME
> sbt
> project akka-sample-remote
> run
Select to run "sample.remote.calculator.CalcApp" which in the case below is number 3:
Multiple main classes detected, select one to run:
[1] sample.remote.calculator.LookupApp
[2] sample.remote.calculator.CreationApp
[3] sample.remote.calculator.CalcApp
Enter number: 3
You should see something similar to this::
[info] Running sample.remote.calculator.CalcApp
[INFO] [12/22/2011 14:21:51.631] [run-main] [ActorSystem] REMOTE: RemoteServerStarted@akka://CalculatorApplication@127.0.0.1:2552
[INFO] [12/22/2011 14:21:51.632] [run-main] [Remote] Starting remote server on [akka://CalculatorApplication@127.0.0.1:2552]
Started Calculator Application - waiting for messages
[INFO] [12/22/2011 14:22:39.894] [New I/O server worker #1-1] [ActorSystem] REMOTE: RemoteClientStarted@akka://127.0.0.1:2553
Open up a new terminal window and run SBT once more:
> sbt
> project akka-sample-remote
> run
Select to run "sample.remote.calculator.LookupApp" which in the case below is number 1::
Multiple main classes detected, select one to run:
[1] sample.remote.calculator.LookupApp
[2] sample.remote.calculator.CreationApp
[3] sample.remote.calculator.CalcApp
Enter number: 1
Now you should see something like this::
[info] Running sample.remote.calculator.LookupApp
[INFO] [12/22/2011 14:54:38.630] [run-main] [ActorSystem] REMOTE: RemoteServerStarted@akka://LookupApplication@127.0.0.1:2553
[INFO] [12/22/2011 14:54:38.632] [run-main] [Remote] Starting remote server on [akka://LookupApplication@127.0.0.1:2553]
Started Lookup Application
[INFO] [12/22/2011 14:54:38.801] [default-dispatcher-21] [ActorSystem] REMOTE: RemoteClientStarted@akka://127.0.0.1:2552
Sub result: 4 - 30 = -26
Add result: 17 + 1 = 18
Add result: 37 + 43 = 80
Add result: 68 + 66 = 134
Congrats! You have now successfully looked up a remote actor and communicated with it.
The next step is to have an actor deployed on a remote note.
Once more you should open a new terminal window and run SBT:
> sbt
> project akka-sample-remote
> run
Select to run "sample.remote.calculator.CreationApp" which in the case below is number 2::
Multiple main classes detected, select one to run:
[1] sample.remote.calculator.LookupApp
[2] sample.remote.calculator.CreationApp
[3] sample.remote.calculator.CalcApp
Enter number: 2
Now you should see something like this::
[info] Running sample.remote.calculator.CreationApp
[INFO] [12/22/2011 14:57:02.150] [run-main] [ActorSystem] REMOTE: RemoteServerStarted@akka://RemoteCreation@127.0.0.1:2554
[INFO] [12/22/2011 14:57:02.151] [run-main] [Remote] Starting remote server on [akka://RemoteCreation@127.0.0.1:2554]
[INFO] [12/22/2011 14:57:02.267] [default-dispatcher-21] [ActorSystem] REMOTE: RemoteClientStarted@akka://127.0.0.1:2552
Started Creation Application
Mul result: 14 * 17 = 238
Div result: 3764 / 80 = 47.00
Mul result: 16 * 5 = 80
Mul result: 1 * 18 = 18
Mul result: 8 * 13 = 104
That's it!
Notice
------
The sample application is just that, i.e. a sample. Parts of it are not the way you would do a "real" application.
Some improvements are to remove all hard coded addresses from the code as they reduce the flexibility of how and
where the application can be run. We leave this to the astute reader to refine the sample into a real-world app.
* `Akka <http://akka.io/>`_
* `SBT <http://https://github.com/harrah/xsbt/wiki/>`_

View file

@ -0,0 +1,18 @@
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
remote {
transport = "akka.remote.netty.NettyRemoteTransport"
netty {
hostname = "127.0.0.1"
port = 0
}
}
extensions = ["akka.cluster.Cluster$"]
cluster {
seed-nodes = ["akka://ClusterSystem@127.0.0.1:2551", "akka://ClusterSystem@127.0.0.1:2552"]
}
}

View file

@ -0,0 +1,28 @@
package sample.cluster
import akka.actor._
import akka.cluster.Cluster
import akka.cluster.ClusterEvent._
object ClusterApp {
def main(args: Array[String]): Unit = {
if (args.nonEmpty) System.setProperty("akka.remote.netty.port", args(0))
// Create an Akka system
val system = ActorSystem("ClusterSystem")
val clusterListener = system.actorOf(Props(new Actor {
def receive = {
case state: CurrentClusterState
println("Current members: " + state.members)
case MembersChanged(members)
println("Current members: " + members)
}
}))
Cluster(system).subscribe(clusterListener, classOf[MembersChanged])
}
}

View file

@ -282,7 +282,7 @@ object AkkaBuild extends Build {
id = "akka-samples",
base = file("akka-samples"),
settings = parentSettings,
aggregate = Seq(camelSample, fsmSample, helloSample, helloKernelSample, remoteSample)
aggregate = Seq(camelSample, fsmSample, helloSample, helloKernelSample, remoteSample, clusterSample)
)
lazy val camelSample = Project(
@ -322,6 +322,13 @@ object AkkaBuild extends Build {
settings = defaultSettings
)
lazy val clusterSample = Project(
id = "akka-sample-cluster",
base = file("akka-samples/akka-sample-cluster"),
dependencies = Seq(cluster),
settings = defaultSettings
)
lazy val tutorials = Project(
id = "akka-tutorials",
base = file("akka-tutorials"),