When to use actors instead of messaging solutions such as WebSphere MQ or Tibco Rendezvous?

38,223

Solution 1

First off the "older" message systems (MQ) are older in implementation but they are a newer in engineering idea of: transactional persistent queues. Scala Actors and Akka maybe a newer implementation but are built on an older concurrency model of Actors.

The two models however end up being very similar in practice because they both are event message based: See my answer to RabbitMQ vs Akka.

If you're going to code only for the JVM then Akka is probably a good choice. Otherwise I would use RabbitMQ.

Also if you're a Scala developer, then Akka should be a no-brainer. However Akka's Java bindings are not very Java-ish and require casting due to Scala's type system.

Also in Java people don't typically make immutable objects which I recommend you do for messaging. Consequently its very easy in Java to accidentally do something using Akka that will not scale (using mutable objects for messages, relying on weird closure callback state). With MQ this is not a problem because the messages are always serialized at the cost of speed. With Akka they are generally not.

Akka also scales better with large amount of consumers than most MQ. This is because for most MQ (JMS, AMQP) clients every queue connection requires a thread... thus lots of queues == lots of permanently running threads. This is mainly a client issue though. I think ActiveMQ Apollo has a non-blocking dispatcher that purportedly fixes that issue for AMQP. The RabbitMQ client has channels that allow you to combine multiple consumers but there are still issues with large number of consumers potentially causing deadlocks or connections to die so generally more threads are added to avoid this issue.

That being said Akka's remoting is rather new and probably still doesn't offer all the reliable message guarantees and QoS that traditional message queues provide (but that is changing everyday). Its also generally peer-to-peer but does I think support server-to-peer which is generally what most MQ systems do (ie single point of failure) but there are MQ systems that are peer-to-peer (RabbitMQ is server-to-peer).

Finally RabbitMQ and Akka actually make a good pair. You can use Akka as a wrapper to RabbitMQ particularly since RabbitMQ does not help you with handling the consumption of messages and routing the messages locally (in a single JVM).

When to choose Akka

  • Have lots of consumers (think millions).
  • Need low latency
  • Open to the Actor concurrency model

Example system: An interactive real time chat system

When to choose MQ

  • Need to integrate with lots of different systems (ie non JVM)
  • Message reliability is more important than latency
  • Would like more tools and admin UI
  • Because of previous points better for long running tasks
  • Would like to use a different concurrency model than Actors

Example system: A scheduled transactional batch processing system

EDIT based on concerned comments

I made an assumption that the OP was concerned with distributed processing which both Akka and Message Queues can handle. That is I assumed he was talking about distributed Akka. Using Akka for local concurrency is an apples to orange comparison to most message queues. I say most because you can apply the message queue model locally as a concurrency model (ie topic, queues, exchanges) which both the Reactor library and simple-react do.

Picking the right concurrency model/library is very important for low latency applications. A distributed processing solution such as a message queue is generally not ideal because the routing is almost always done over the wire which is obviously slower than within application and thus Akka would be a superior choice. However I believe some proprietary MQ technologies allow for local routing. Also as I mentioned earlier most MQ clients are pretty stupid about threading and do not rely on non-blocking IO and have a thread per connection/queue/channel... ironically non-blocking io is not always low latency but is generally more resource efficient.

As you can see the topic of distributed programming and concurrent programming is rather large and changing everyday so my original intention was not confuse but rather focus on one particular area of distributed message processing which is what I though the OP was concerned with. In terms of concurrency one might want to focus their searches on "reactive" programming (RFP / streams) which is a "newer" but similar model to the actor model and message queue model of which all of these models can be generally combined because they are event based.

Solution 2

I'm not an expert in messaging systems, but you can combine them with Akka in your apps, getting the best of both worlds. Here's an example that you might find useful for experimenting with Akka and messaging systems, in this case ZeroMQ:

https://github.com/zcox/akka-zeromq-java

Solution 3

Akka-Camel would be a better example than ZeroMQ - ZeroMQ is a direct tcp to tcp communication (hence zero - there is no message queue).

With AkkaCamel you can abstract away the queue and produce/consume messages direct from an actor without any code to deal with the message queue message pushing/pulling.

You can forego akka-zeromq and use Akka directly with remoting. I think akka-zeromq is being removed from the core library but we built a good zeromq library for akka called scala-zeromq (https://github.com/mDialog/scala-zeromq)

Akka has a couple key core use cases:

1) Mutable state

It's easier to handle shared state by hiding it in an actor. As actors handle messages synchronously, you can hold state in an actor and expose that field with high consistency via the actor API

2) Distribution

Concurrency is free in akka so you say it's really about solving distribution problems. Distribution across machines and cores. Akka has build in "location transparency" for sending messages over the wire. It has clustering and patters associated for scaling up a single service as well. This makes it a very good solution for distribution (eg micro-service architecture)

Here is an example of using Akka with ActiveMQ with Akka-Camel (using Java8)

import akka.actor.Props;
import akka.camel.Camel;
import akka.camel.CamelExtension;
import akka.testkit.TestActorRef;
import akka.testkit.TestProbe;
import org.junit.Ignore;
import org.junit.Test;
import akka.camel.javaapi.UntypedProducerActor;
import akka.camel.javaapi.UntypedConsumerActor;
import static com.rogers.totes.TotesTestFixtures.*;
import org.apache.activemq.camel.component.*;

public class MessagingTest {
    @Test @Ignore
    public void itShouldStoreAMessage() throws Exception{
        String amqUrl = "nio://localhost:61616";
        Camel camel = (Camel) CamelExtension.apply(system);
        camel.context().addComponent("activemq", ActiveMQComponent.activeMQComponent(amqUrl));

        TestProbe probe = TestProbe.apply(system);
        TestActorRef producer = TestActorRef.create(system, Props.create((Producer.class)));
        TestActorRef consumer = TestActorRef.create(system, Props.create((Consumer.class)));
        producer.tell("Produce", probe.ref());

        Thread.sleep(1000);
    }
}

class Producer extends UntypedProducerActor{

    @Override
    public String getEndpointUri() {
        return "activemq:foo.bar";
    }
}

class Consumer extends UntypedConsumerActor{

    @Override
    public String getEndpointUri() {
        return "activemq:foo.bar";
    }

    @Override
    public void onReceive(Object message) throws Exception {
        System.out.println("GOT A MESSAGE!" + message);

    }
}
Share:
38,223

Related videos on Youtube

Kai Wähner
Author by

Kai Wähner

I am an IT-Consultant in the Java / JEE / SOA world working in Munich, Germany for MaibornWolff et al (www.mwea.de)

Updated on July 08, 2022

Comments

  • Kai Wähner
    Kai Wähner almost 2 years

    I've already read the question and answers to What design decisions would favour Scala's Actors instead of JMS?.

    Usually, we use messaging solutions which have existed for years already: either a JMS implementation such as WebSphere MQ or Apache ActiveMQ is used for Point-To-Point communication, or Tibco Rendevous for Multicast messaging.

    They are very stable, proven and offer high availability and performance. Nevertheless, configuration and setup seem much more complex than in Akka.

    When and why should I use Akka for some use cases where the aforementioned products - WebSphere MQ or ActiveMQ - have been used successfully so far? Why should I consider using Akka instead of WebSphere MQ or Tibco RV in my future project?

    And when should I avoid Akka? Does it offer the same high availability and performance as the other solutions? Or is it a bad idea to even compare Akka to the other messaging middlewares?

    Maybe there also is another messaging solution in the JVM environment which I should consider besides JMS (Point-to-Point), TibcoRV (Multicast) and Akka?

  • Vladimir Matveev
    Vladimir Matveev over 11 years
    ZeroMQ is not exactly a messaging system. It is rather some kind of improved sockets. Full-fledged messaging systems are much more complex than ZeroMQ. The project at your link seems to be just a thin wrapper around ZeroMQ with Akka.
  • Igor S.
    Igor S. over 9 years
    I think an answer to a wrong question can't be right. You can't compare a message queue and a concurrency model. They are built to solve COMPLETELY different tasks and have in common only the "message" word.
  • Adam Gent
    Adam Gent over 9 years
    Well yes and no. Akka supports distributed messaging and you could very easily build concurrency model off of message queue paradigm (google Spring's Reactor). Really the only distinction now is that RabbitMQ has durable messages.. oh wait Akka supports that now also. He may say "Actor" in the title but explicitly points out Akka which does have massive overlap with many message based systems (both concurrent and distributed).
  • Adam Gent
    Adam Gent over 9 years
    BTW @IgorS. the typically concurrency model used with message queues is called SEDA (staged event driven architecture). Besides using Queues, Topics, and Exchanges is a concurrency model in itself (that just happens to be distributed model also.. just like the actor model). I also really despise when someone says "wrong question".. besides inappropriate questions, when can a question be wrong? Its snarky and elitist to say something like that.
  • Igor S.
    Igor S. over 9 years
    The question is wrong not in the sense that the author shouldn't ask it. The opposite is true - it should've been asked, but it involves comparing a message broker implementation and an actor model framework. If I was asked about EDA I wouldn't even mention concurrency as an advantage of this approach, but scalability, problem decomposition, loose coupling, maintainability in the long run, SLA adherence - everything except concurrency. But if I was asked about how to implement highly concurrent system that can handle millions of concurrent requests - then actor model comes to play.
  • Igor S.
    Igor S. over 9 years
    So I know that you can abstract away from the original intention of akka and rabbitMQ and say "they both support messaging" and thus are comparable, but I'm trying to think about a problem where akka and rabbitmq will be interchangable and can't find one.
  • Adam Gent
    Adam Gent over 9 years
    I never said they were interchangeable. I even say they work great together and why. But he clearly is talking about distributed akka here and not akka the actor library. That's how I read it. Feel free to edit my post as your point is valid and could confuse others that stumble on the post.
  • Adam Gent
    Adam Gent over 9 years
    @IgorS. I tried fixing the answer but it is rather difficult because adding concurrency makes the answer too broad but I hope maybe it will help others.
  • Rob Crawford
    Rob Crawford over 6 years
    One the Akka Java API -- it's very clean now, especially with JDK 8 lambdas. I suspect it will get better if/when they introduce value objects with JDK 10.