An Introduction to Akka Clustering

DZone 's Guide to

An Introduction to Akka Clustering

Click here to learn the basics of Akka clustering.

· Java Zone ·
Free Resource

This article was first published on the Knoldus blog.

Akka cluster provides a fault-tolerant, decentralized, peer-to-peer cluster membership service with no single point of failure or single point of bottleneck. It does this using gossip protocol and an automatic failure detector.

Node is a logical member of a cluster; there could be multiple nodes in a single machine. It is defined by a hostname:port:uid. UID is not user-visible; most of the time, it used by the Akka internally to identify whether it is the same system or system on the same node and port.

Cluster is a set of node drawing together through the cluster membership protocol. Cluster assigned a special leadership role to a node in the cluster. It will manage cluster convergence, such as down and up events. Akka cluster is not a SPOF (single point of failure), and it is fine if a node fails, another node will take over immediately.

There is also a seed node as you can see in the above image. The seed nodes are configured contact points for new nodes joining the cluster. When a new node starts, it sends a message to all seed nodes and then sends join command to the seed node which answers first.

In Akka cluster, there is a membership lifecycle for every node. The node begins with the joining state. Once all the nodes have seen that a new node is joining through a gossip protocol, the leader will set a node in "up". If the node leaving the cluster is safe, it switches to the leaving state. Once the leader sees the node in the leaving state, the leader will set a node in the existing state and once all other nodes see the existing state, the leader will remove the node from the cluster and mark it as removed. If something abnormal happens on the node, it is set unreachable until the leader decides to mark it "down". This could happen only when auto-downing is enabled or Akka split brain is used or an operator on node invokes the down command explicitly.

So, let’s start with the basic configuration.

The following configuration enables the Cluster extension to be used. It joins the cluster and an actor subscribes to cluster membership events and logs them:

akka {
actor {
provider = "cluster"
remote {
log-remote-lifecycle-events = off
netty.tcp {
hostname = ""
port = 0

cluster {
seed-nodes = [

# auto downing is NOT safe for production deployments.
# you may want to use it during development, read more about it in the docs.
# auto-down-unreachable-after = 10s

# Enable metrics extension in akka-cluster-metrics.

# Sigar native library extract location during tests.
# Note: use per-jvm-instance folder when running multiple jvm on one host.

Joining to Seed Nodes

akka.cluster.seed-nodes = [

Now, let’s create a simple cluster listener:

class SimpleClusterListener extends Actor with ActorLogging {

val cluster = Cluster(context.system)

// subscribe to cluster changes, re-subscribe when restart
override def preStart(): Unit = {
cluster.subscribe(self, initialStateMode = InitialStateAsEvents, classOf[MemberEvent], classOf[UnreachableMember])
override def postStop(): Unit = cluster.unsubscribe(self)

def receive = {
case MemberUp(member) =>
log.info("Member is Up: {}", member.address)
case UnreachableMember(member) =>
log.info("Member detected as unreachable: {}", member)
case MemberRemoved(member, previousStatus) =>
log.info("Member is Removed: {} after {}", member.address, previousStatus)
case _: MemberEvent => // ignore

The actor registers itself as a subscriber of certain cluster events. It receives events corresponding to the current state of the cluster when the subscription starts and then it receives events for changes that happen in the cluster.

That’s all for this blog!

akka ,cluster ,clustering ,java ,node

Published at DZone with permission of Prabhat Kashyap , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}