“I want to run my Akka Cluster. How do I do that on Pivotal Cloud Foundry (PCF)?”
We’ve been getting this question lately. It’s no surprise, given PCF's cloud-native operational scale, and Akka's strengths as a high-performance messaging toolkit.
What is Akka?
Akka is an actor-based message-driven toolkit for managing concurrency, elasticity and resilience on the JVM. The toolkit supports both Java and Scala. Akka is an open-source project, available under the Apache 2 License.
PCF supports a variety of JVM-based frameworks (plus .NET, Go, NodeJS, and others). This makes Akka a natural workload for the platform.
Why would you run Akka on PCF? Here’s what we tell customers:
-
Platform security and visibility
Plus, you can run Akka Cluster with TCP or UDP – PCF supports both protocols.
Now you know why Akka is well-suited for PCF. How do you go about setting it up? Glad you asked. Let’s dive in!
Tutorial: Up and Running with Akka Cluster on PCF
What follows is a short guide to walk you through how to deploy and run Akka Cluster-based applications.
Akka Cluster is based on TCP communication. Or, you can opt for UDP in Akka versions 2.4.11 and higher. As mentioned earlier, PCF supports both options. That’s because the platform’s embedded container-to-container networking (C2C) mechanism allows apps to talk to other apps via TCP or UDP. Client applications can access the Akka Cluster via both HTTP(S) and TCP.
Akka Cluster's seed nodes are essential for starting the cluster. They serve as the first point of contact for other nodes joining the cluster. Which brings us to another benefit of running Akka Cluster on PCF. With PCF, there is no need to write code to register every seed node with an external system like etcd, Zookeeper, or Consul. Instead, we can use the new polyglot service discovery capabilities to generate index-based routes for each instance of that app. From there, you can access each seed node using instance-based DNS.
We will also demonstrate how easy it is to dynamically scale your Akka Cluster to handle an increase in demand. As an application is scaled, PCF updates the index-based routes automatically for you.
Prerequisites
In this example, we assume you have the following:
-
The latest Cloud Foundry command-line interface (a.k.a. cf CLI)
-
This git repo cloned somewhere
-
Access to a Pivotal Cloud Foundry foundation, either:
-
Pivotal Web Services (PWS)
-
On-premises, PCF version 2.2 or higher
-
-
At least 3 GB of available memory in your PCF quota. (NOTE: PWS offers a free trial with up to 2 GB of memory.)
Get Ready to Deploy Apps to PCF
Login to your Pivotal Cloud Foundry foundation using its API URL via the cf login command
. If you are using on-prem PCF, please ask your PCF admin. If you are using PWS you can issue this command:
cf login -a https://api.run.pivotal.io
When prompted, please enter your PCF credentials.
Target the org and space where you want to deploy your apps:
cf target [-o ORG] [-s SPACE]
Build the Akka Application
You can deploy an Akka application using PCF’s java-buildpack. Our sample application is inspired by akka-sample-cluster. It has backend nodes that calculate a factorial upon receiving messages from frontend nodes. Frontend nodes also expose HTTP interface GET <frontend-hostname>/info
that shows number of jobs completed.
After you cloned this project from Github, go to your local repo's folder:
cd
akka
-sample-cluster-on-cloudfoundry/akka-sample-cluster/
To ensure the URL for your app is unique from other apps in PCF, please change the value of the seed-host
entry in the file src/main/resources/application.conf
from:
seed-host = "
akka
-backend.apps.internal"
to something like:
seed-host = "akka-backend-[unique_name].apps.internal"
Now you are ready to compile and package both Akka backend and frontend components:
sbt
backend
:assembly
# backend
sbt
frontend
:assembly
# frontend
Deploying Akka Backend Application
Deploy, but do not start yet, sample Akka backend: with --no-route
and --health-check-type none
options since backend doesn't expose any HTTP ports. Substitute akka-backend-[unique_name]
with the name you chose for the seed-host property.
Note: the name of the Java buildpack varies depending on whether you are deploying on-premises (java_buildpack_offline
) or on Pivotal Web Services (java_buildpack
). Make sure you use the right name when you push your app.
cf push --no-start --health-check-type none akka-backend-[unique_name]
-m 768M -p target/scala-2.12/akka-sample-backend.jar
-b java_buildpack -d apps.internal
In addition, the app uses a PCF shared domain for internal routes called apps.internal. Applications that use internal routes will be directly communicating over the container network, instead of having traffic routed out and back in through the load balancer and GoRouter. For more details on this capability, please check this cloudfoundry.org blog post.
Add this network policy to allow all app instances of the backend nodes to communicate:
cf add-network-policy akka-backend-[unique_name] --destination-app
akka-backend-[unique_name] --port 2551 --protocol
tcp
Before starting the backend app, open another terminal window and tail the app logs. Please note log messages will appear after you start the backend app:
cf logs akka-backend-[unique_name]
Start the backend app:
cf start akka-backend-[unique_name]
After the app starts, switch to the other terminal window to check the logs to see that the first node joined itself
Dynamically Scaling Akka Backend Application
IMPORTANT: To prevent cluster split, verify that the first node is running before scaling it.
Scale backend to 2 app instances:
cf scale akka-backend-[unique_name] -i 2
Deploying Akka Frontend Application
Deploy, but don't yet start, the sample Akka frontend. Substitute akka-frontend-[unique_name]
with a unique name.
Once again, the name of the Java buildpack varies depending on whether you are deploying on-premises (java_buildpack_offline
) or on Pivotal Web Services (java_buildpack
). Make sure you use the right name when you push your app.
cf push akka-frontend-[unique_name] --no-start
-m 768M -p target/scala-2.12/akka-sample-frontend.jar -b java_buildpack
Add this network policy to allow frontend app to communicate with backend app via backend's TCP:2551 port:
cf add-network-policy akka-frontend-[unique_name] --destination-app
akka-backend-[unique_name] --port 2551 --protocol
tcp
Before starting the frontend app, open another terminal window and tail the app logs. Please note log messages will appear after you start the frontend app:
cf logs akka-frontend-[unique_name]
Start the fronted app:
cf start akka-frontend-[unique_name]
After the fronted app starts, switch to the other terminal windows to check logs from both frontend and backend apps to ensure all client/server and server-to-server communications are working fine.
Verify that the frontend and backend apps are working:
curl akka-frontend-[unique_name].<YOUR_PCF_DOMAIN>/info
If all is working as expected, it should show the number of completed jobs!
Summary
We’ve shown you how to get Akka Cluster up and running quickly. And you’ve seen how easy it is to scale according to load. Now, you are ready to deploy your own Akka Cluster to PCF. Run Akka Cluster on PCF, and immediately enjoy many production-grade features out-of-the-box!
Special thanks to our friends at Lightbend for their assistance on this post!
Want to learn more about Pivotal Cloud Foundry? Join us at SpringOne Platform in Washington, D.C., September 24 to 27. Register now.