Akka remoting via kafka

Hi,

I wonder if it is possible and makes sense to implement an alternative akka remoting transport in which messages to remote actors would be sent and received via kafka (or any other persistent message queue for that matter)?

Thanks
Vadim

What’s the use case? I assume you’re aware of the Akka Streams connector for Apache Kafka?

this is a completely different use case. Streams allow you to build up an in-process transformation chain, if you will, it is a building block to be used within a service for example. If I am building a system of microservices and want to abstract away the way the services communicate between themselves (via akka remoting with tcp, http, kafka etc.). I just want to message ! recipient. A persistent message queue such as kafka would allow for services to be unavailable and come back up without loosing communication. An ESB of sorts

Akka message queues can be persistent. Classic Persistence • Akka Documentation

Are you meaning the Kafka Producer could still send messages while the Consumer is not available? Is that the semantic you’re after?

akka persistence is mostly about recovery of state. It is a persistence INSIDE, what I am thinking of is persistence OUTSIDE of a service, asynchronous persistent loosely coupled scalable communication between services reusing the syntax of akka actor message sending, with all of its benefits - location transparency, simplicity etc.

1 Like

I’m not sure that’s true. The AsyncWriteJournal combined with AtLeastOnceDelivery suggests that the mailbox is also persistent.

journaled messages are replayed to that actor so that it can recover internal state from these messages.

not sure I understand. Let’s say an actor from ServiceA sends a remote message to an actor in a ServiceB (on a different JVM and akka system) and ServiceB is currently unavailable - where is this message persisted? in the journal of the ServiceA? And you are saying that this message will be delivered to ServiceB whenever it comes back to life?

This can be a reasonable goal, but I think akka-remoting is not a good fit: akka-remoting is an Akka-specific bidirectional transport mechanism for communication between Akka nodes, and has things like heartbeating, availability tracking etc. In a microservices architecture you’d likely want to use a technology-agnostic transport mechanism between nodes, such as HTTP or, indeed, Kafka.

If you want to abstract away the communication mechanism, indeed you could model your transport as an actor, and have the consumer be independent of which transport is used to actually send the events/messages.

1 Like

Indeed AtLeastOnceDelivery can be used in a PersistentActor to retry delivery of a message, even across system restarts. This does mean all the information in your message is persisted in that PersistentActor - which is great when that actor is already storing this state with event sourcing and akka-persistence. For situations where you are no longer interested in the data as soon as it has been successfully delivered, however, it might not be a great fit.

1 Like

it is still a somewhat different use case. For starters sending and delivery are not decoupled - the message in the journal will not be delivered until you restart the sending system. And then this is just part of the story. I was actually looking to reuse Akka’s DSL (tell and ask) but without necessarily having to use the default Akka’s transport, and that’s the main driving factor. I like to be able not to mix the business communication code with other concerns (serialization, transport etc). Wouldn’t it be nice to be able to just write

serviceB ! userRequest

and have the configuration deal with the actual implementation (again - serialization, kafka enqueuing, dequeuing, topic creation, address resolution, logging etc) or may be switching between kafka and netty remoting in unit and integration tests

I’m confused what you are referring to here ;)

Yes, that seems reasonable, and possible to do by implementing serviceB as an actor that takes care of the implementation stuff (serialization, kafka enqueuing, dequeuing, topic creation, address resolution, logging etc), right? This will have to happen somewhere, after all ;). My bet is that doing this in that actor will be simpler than trying to fit it into akka-remoting.

2 Likes

That is exactly what I would like to avoid :) The idea was to separate business logic from implementation details (after all serialization, logging, transport are all implementation details). AOP style like

1 Like

I agree it makes sense to separate the messaging implementation details from the business logic. I think you can achieve that by putting your business logic in one (set of) actor(s), and putting the implementation details in another, separate actor. I don’t see how putting the implementation details in akka-remoting instead of in a (separate) actor would give you any benefit.

You’re of course welcome to try and write that Kafka-based akka-remoting transport, that might highlight some of the pros/cons of this approach - but I’m pretty confident modeling it as an actor will be easier and more flexible, while providing the same isolation/abstraction benefits.

I agree with you, this would be a very usefull addition to Akka

I went through the whole thread. I was literally thinking of the same approach using Kafka to have distributed system of different microservices which can be small actor apps or may be using completely different tech stack. My microservices will be mainly java actor based but using remoting to achieve loose coupling of code is hard for my approach. Hence, I decided to go Kafka route as well.

My next question (as already asked by @leporello), is there a way to integrate it with actors instead of going through stream connector?

Many thanks in advance. :slight_smile:

I think Alpakka Kafka is the easiest way to connect your application to Kafka, and is indeed streams-based - but you can connect streams to actors, for example by using the stream ask operator.

Didn’t Colin Breck already show the way for this ?

Here for instance ?

You could then just run a Kafka producer inside the actor no ?

1 Like