DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Coding
  3. Java
  4. Message Routing in Akka

Message Routing in Akka

Here's an introductory article on message routing in Akka with Scala.

Efthymios Vafeiadis user avatar by
Efthymios Vafeiadis
CORE ·
Mar. 19, 19 · Tutorial
Like (9)
Save
Tweet
Share
13.75K Views

Join the DZone community and get the full member experience.

Join For Free

In many modern software products, there is a need to accept heavy traffic load, perform multitasking, and run procedures in parallel. Systems have multiple execution cores for executing multiple tasks at the same time rather than sequentially with multithreading engineering.

This makes the system faster but it also causes issues, like shared memory problems. Solutions like locking can protect shared memory values and are fully supported by JVM languages. The drawback is that there is a more complicated code implementation. On the other hand, Akka Actor model is an alternative. The Actor Model provides a higher level of abstraction for writing concurrent and distributed systems.

It also alleviates the developer from having to deal with explicit locking and thread management, making it easier to write concurrent and parallel systems. Actors are objects that encapsulate state and behavior and communicate exclusively by exchanging messages, which are placed into the recipient’s mailbox. Many companies and open-source projects use Akka to develop concurrent systems; Paypal's transaction handling is a very interesting case study.

This is an article about routing in Akka — it would be nice to have the minimum familiarity with Actor model and Scala to get the most out of it.

How to Implement Routing in Akka

In some cases, we may need a specific type of message routing mechanism for specific requirements like:

  • Send messages to the less busy actor among other actors of the same type, that is, to the actor with the lowest number of messages.
  • Send messages to actors with a round-robin algorithm, that is, send messages one by one to all actors in a loop.
  • Send a single message to all the actors in a specific group to redistribute the work among actors automatically with the help of some mechanism.
  • Routing allows messages to be routed to one or more actors known as routees, by sending the messages to a router that will know how to route the messages to the routees.

Types of Routing Strategy

In Akka, there are many routing strategies, such as :

  •  RoundRobin: Routes in a round-robin fashion to its routees.
  •  Random: This router type selects one of its routees randomly for each message.
  •  SmallestMailBox: A Router that tries to send to the non-suspended child routee with fewest messages in mailbox.
  •  Broadcast: A broadcast router forwards the message it receives to all its routees.
  •  ScatterGatherFirstCompleted: The ScatterGatherFirstCompletedRouter will send the message on to all its routees. It then waits for the first reply it gets back. This result will be sent back to the original sender. Other replies are discarded.
  •  TailChopping: The TailChoppingRouter will first send the message to one, randomly picked, routee and then after a small delay to a second routee and so on.
     It waits for the first reply it gets back and forwards it back to the original sender. Other replies are discarded.

How Routing Is Designed Within Akka

Routers look like normal actors, but in reality, they are implemented in a different way. Routers are designed to be extremely efficient at receiving messages and passing them quickly on to routees. A normal actor can be used for routing messages, but an actor's single-threaded processing can become a bottleneck. Routers can achieve much higher throughput with optimization to the usual message-processing pipeline that allows concurrent routing.

This is achieved by embedding routers' routing logic directly in their ActorRef rather than in the router actor. Messages sent to a router's ActorRef can be immediately routed to the routee, bypassing the single-threaded router actor entirely. The cost to this is, of course, that the internals of routing code are more complicated than if routers were implemented with normal actors.

Below I present a simple routing implementation with RoundRobin and Broadcast.

Setup

At first, we need to create an sbt Scala project in our IDE — I prefer IntelliJ — with Akka dependencies.

name := "akka-routing"

version := "0.1"

scalaVersion := "2.12.7"

val akkaVersion = "2.5.13"

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-actor" % akkaVersion,
  "com.typesafe.akka" %% "akka-testkit" % akkaVersion,
  "org.scalatest" %% "scalatest" % "3.0.5"
)


Round Robin Router

Let's begin by creating an example of a Round Robin Router. As we said before, in this case, the router will send messages one by one to all actors in a loop, as described in the following schema.

Round Robin Router

At first, we will create an Actor let's call it RoundRobinActor.

package actors

import akka.actor.{Actor, ActorLogging}

class RoundRobinActor extends Actor with ActorLogging {

  override def receive = {
    case msg: String => log.info(s" I am ${self.path.name}")
    case _ => log.info("Unknown message ")
  }

}


Then, we will test it by creating a RounRobinPool of two actors and route four "hello" messages.

import actors.RoundRobinActor
import akka.actor.{ActorSystem, Props}
import akka.routing.RoundRobinPool

object RoundRobinPoolApp extends App {
  val actorSystem = ActorSystem("Akka-RoundRobin-Example")
  val router = actorSystem.actorOf(RoundRobinPool(2).props
    (Props[RoundRobinActor]))
  for (i <- 1 to 4) {
    router ! s"Hello $i"
  }

}


As we can see in the console, the message routed all routees with the Round Robin algorithm by creating a loop.

[akka://Akka-RoundRobin-Example/user/$a/$a]  I am $a
[akka://Akka-RoundRobin-Example/user/$a/$b]  I am $b
[akka://Akka-RoundRobin-Example/user/$a/$a]  I am $a
[akka://Akka-RoundRobin-Example/user/$a/$b]  I am $b


Broadcast Router

Now, let's create an example for Broadcast Router. As we said, the Broadcast Router will forward the message to all its routees, as we can see in the following schema.

Broadcast Router


Again, we will create an Actor; let's call it BroadcastActor.

package actors

import akka.actor.{Actor, ActorLogging}

class BroadcastActor extends Actor with ActorLogging {
  override def receive = {
    case msg: String => log.info(s" $msg, I am ${self.path.name}")
    case _ => log.info("Unknown message ")
  }

}


Then, we will test it by creating a BroadcastPool of three actors and route the message "hello."

import actors.BroadcastActor
import akka.actor.{ActorSystem, Props}
import akka.routing.BroadcastPool

object Broadcastpool extends App {
  val actorSystem = ActorSystem("Akka-Example-Broadcast")
  val router =
    actorSystem.actorOf(BroadcastPool(3).props
    (Props[BroadcastActor]))
  router ! "hello"

}



As we can see in the console, the message broadcasted successfully to all routees.

 [akka://Akka-Example-Broadcast/user/$a/$c]  hello, I am $c
 [akka://Akka-Example-Broadcast/user/$a/$a]  hello, I am $a
 [akka://Akka-Example-Broadcast/user/$a/$b]  hello, I am $b


This article was an introduction about message routing in Akka with Scala.

Happy routing!

Akka (toolkit) Round-robin (document) Shared memory Open source Scala (programming language) Schema Memory (storage engine) Implementation

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Choosing the Right Framework for Your Project
  • What Is API-First?
  • What “The Rings of Power” Taught Me About a Career in Tech
  • Documentation 101: How to Properly Document Your Cloud Infrastructure Project

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: