Akka.NET 1.2: Production-ready Akka.Cluster.Tools and Akka.Streams

TLS support for Akka.Remote, Coordinated Shutdown, Performance Improvements, and More

A ton of work has gone into Akka.NET thus far in 2017, and the biggest release we’ve done since last year’s Akka.NET 1.1 release just hit NuGet: Akka.NET v1.2.

Akka.NET v1.2 is the culmination of months of work on many different fronts at once, and you can read the official Akka.NET 1.2 release notes here. In this post we’re going to explain the significance of the 1.2 release and what it means for the end-users of Akka.NET.

Akka.Streams and Akka.Cluster.Tools Released from Beta

The most notable part of the release is what’s coming out of beta: Akka.Streams and Akka.Cluster.Tools. Both of these modules now have stable APIs and are considered to be sufficiently well-tested and well-used (measured by adoption and usage during its beta period) to be considered full production-ready modules.

Akka.Streams is a subject we intend to cover at length as it’s an amazing, higher-level abstraction built on top of Akka.NET actors that allows end-users to express powerful flows in just a few lines of code. Petabridge has been using Akka.Streams in a number of our consulting projects for months now and both we and our customers are impressed with its conciseness and power.

Akka.Cluster.Tools is built on top of Akka.Cluster and introduces three additional capabilities:

  • Distributed Publish and Subscribe, which we’ve written about recently on the Petabridge blog. In essence this module can be used to create a decentralized message broker that allows Akka.NET actors to subscribe and publish to various user-defined “topics” across the cluster. This can be done transparently without needing to know which subscribers and which publishers are on each node.
  • Cluster Singleton, which is used to help create reliable singleton actors inside a cluster. I.E. you can guarantee that only a single actor of a particular type exists at any time in a given cluster. Should that singleton be placed on a node that later becomes unreachable, that singleton will be moved to different node instead. This tool is useful for scenarios like job tracking, scheduling, and so forth where a particular feature is most easily and effectively implemented when a single actor is responsible for it.
  • Cluster Client - if you think of your Akka.Cluster as a type of stand-alone application, what happens if you want to have other services outside your cluster consume that application as clients? This is where ClusterClient comes in; it’s a tool designed to allow external services to learn the topology of your cluster and communicate with actors inside of it without becoming part of the cluster itself.

All of these capabilities are now available as part of the stable Akka.Cluster.Tools package.

DotNetty Transport and TLS Support for Akka.Remote

One of the biggest changes to an existing module in Akka.NET v1.2 was our migration from the Helios 2.* transport to a new, DotNetty-based transport. DotNetty and Helios were both .NET implementations of the famous Netty project in Java, but DotNetty is supported by Microsoft as part of the Azure IoT hub and rather than continue to maintain Helios, we opted to simply join forces with Microsoft and both contribute to and use their technology.

Here’s the relevant bullet points for the DotNetty transport in Akka.NET 1.2:

  • Fully backwards compatible with the existing Helios transports; you can have some nodes running Helios and some running DotNetty and both will be able to inter-operate with no issues whatsoever.
  • Fully backwards compatible with the HOCON configuration used for Helios; if you upgrade an existing Akka.NET 1.* application to DotNetty you won’t need to edit your configuration. It will just work. However, the DotNetty transport does support some additional features and options not supported by Helios.
  • TLS Support - this is the biggest change introduced to Akka.Remote by the DotNetty transport. Full support for TLS and public key cryptography inside the Akka.Remote transport itself. More on that in a moment.
  • .NET Standard Support - we’re working feverishly towards our goal of delivering a version of Akka.NET that is fully .NET Standard-compliant, and our transport layer was one of the biggest areas of concern in this regard. DotNetty supports .NET Standard 1.3 and thus will enable Akka.NET to support at least that version of the .NET Standard going forward.
  • Improved Performance - DotNetty has additional buffer and concurrency performance optimizations that Helios 2.* does not have, thus at the transport layer there should be a noticeable decrease in the amount of garbage collection and allocations occurring under the hood there.

The most important change in all of this is the new TLS support, which you can enable via the following HOCON:

akka {
  loglevel = DEBUG
  actor {
    provider = Akka.Remote.RemoteActorRefProvider,Akka.Remote
  }
  remote {
    dot-netty.tcp {
      port = 0
      hostname = 127.0.0.1
      enable-ssl = true
      log-transport = true
      ssl {
        suppress-validation = true
        certificate {
          # valid ssl certificate must be installed on both hosts
          path = "<valid certificate path>" 
          password = "<certificate password>"
          # flags is optional: defaults to "default-flag-set" key storage flag
          # other available storage flags:
          #   exportable | machine-key-set | persist-key-set | user-key-set | user-protected
          flags = [ "default-flag-set" ] 
        }
      }
    }
  }
}

DotNetty’s TLS implementation loads X509Certificates from the file system and can verify the certificate’s authenticity via password. In effect, this gives both parties (the two ActorSystem instances connecting via Akka.Remote) the ability to authenticate each other as the same valid SSL certificate must be found on both systems with the same password in order for TLS to be enabled successfully. All Akka.Remote does is expose these settings through the HOCON shown above.

TLS support is typically not needed in most environments where Akka.Remote is used; however, if you plan on using Akka.Remote across the open Internet for use cases such as multi-datacenter deployments or true client-server applications, then TLS support is a must.

CoordinatedShutdown

One of the major pain points of Akka.Cluster that users have raised with us since the Akka.NET 1.1 release was the process for gracefully terminating an Akka.Cluster node that needed to be replaced, upgraded, or removed. More accurately, it was the lack of process that users took issue with.

In Akka.NET v1.2 we introduced a new feature built directly into the core Akka module called CoordinatedShutdown, which automates the process of gracefully cleaning up cluster nodes.

By default, if you want to gracefully terminate an Akka.Cluster node and subsequently terminate your ActorSystem, then just call the following piece of code:

CoordinatedShutdown.Get(myActorSystem).Run();

Conversely, if you call Cluster.Leave and initiate the cluster exit process that way, that will also cause CoordinatedShutdown.Run() to be invoked. CoordinatedShutdown is highly extensible and includes all sorts of additional options (including one that triggers CoordinatedShutdown.Run() on process exit) so if you’re interested in learning more about how it works, read the CoordinatedShutdown documentation here.

For even more details, see the release notes and the full set of milestone issues for Akka.NET 1.2 here.

Coming Up Next

We’ll publish an updated roadmap soon, but here’s the breakdown of the high level goals for the immediate future:

  1. .NET Standard Support - Akka.NET’s number one organizational goal at the moment and will happen as part of Akka.NET 1.5;
  2. Akka.Persistence Stable release - we’re on the verge of doing this already, but are working on a serialization standard for all Akka.Persistence plugin implementations that will allow Akka.Persistence to better utilize native database capabilities;
  3. Akka.Persistence Plugin cleanup and releases - we’ve been feverishly getting all of the official Akka.NET persistence plugins updated and are putting them all onto a much more structured release train so we can update them more regularly and expand the area of unit testing coverage for each;
  4. Akka.Cluster.Sharding and Akka.DistributedData releases - more features for Akka.Cluster users.

Thanks for your support and for your continued patronage of Akka.NET! We appreciate it!

If you liked this post, you can share it with your followers or follow us on Twitter!
Written by Aaron Stannard on April 17, 2017

 

 

Observe and Monitor Your Akka.NET Applications with Phobos

Did you know that Phobos can automatically instrument your Akka.NET applications with OpenTelemetry?

Click here to learn more.