首先,“较旧的”消息系统(MQ)在实现上较旧,但在工程设计上却较新:事务持久队列。Scala Actors和Akka可能是较新的实现,但它们是基于Actors的较旧并发模型构建的。
但是,这两种模型实际上在实践中非常相似,因为它们都是基于事件消息的:请参阅我对RabbitMQ vs Akka的回答。
如果只打算为JVM编写代码,那么Akka可能是一个不错的选择。否则,我将使用RabbitMQ。
另外,如果您是Scala开发人员,那么Akka应该是明智的选择。但是,由于Scala的类型系统,Akka的Java绑定不是Java风格的,并且需要强制转换。
同样在Java中,人们通常不会创建不可变的对象,而我建议您这样做来进行消息传递。因此,在Java中很容易意外地使用Akka进行无法扩展的操作(使用可变对象作为消息,依赖于怪异的闭包回调状态)。使用MQ,这不是问题,因为消息总是以速度为代价进行序列化。对于Akka,他们通常不是。
与大多数MQ相比,Akka在拥有大量消费者的情况下也具有更好的伸缩性。这是因为对于大多数MQ(JMS,AMQP)客户端而言,每个队列连接都需要一个线程...因此,许多队列==大量永久运行的线程。不过,这主要是客户问题。我认为ActiveMQ Apollo有一个非阻塞调度程序,据称可以解决AMQP的问题。RabbitMQ客户端具有允许您组合多个使用者的通道,但是仍然存在大量使用者可能导致死锁或连接死亡的问题,因此通常添加更多线程来避免此问题。
话虽这么说,Akka的远程处理是相当新的,可能仍未提供传统消息队列提供的所有可靠消息保证和QoS(但每天都在变化)。它通常也是点对点的,但是我认为它支持服务器对点,这通常是大多数MQ系统所做的(即单点故障),但是有些MQ系统是点对点的(RabbitMQ是服务器对等的)。对等)。
最后,RabbitMQ和Akka实际上组成了很好的一对。您可以将Akka用作RabbitMQ的包装器,特别是因为RabbitMQ不能帮助您处理消息的使用和本地路由消息(在单个JVM中)。
何时选择Akka
- 有很多消费者(想想数百万)。
- 需要低延迟
- 向Actor并发模型开放
系统示例:交互式实时聊天系统
何时选择MQ
- 需要与许多不同的系统集成(即非JVM)
- 消息可靠性比延迟更重要
- 需要更多工具和管理界面
- 由于先前的观点对于长期运行的任务更好
- 想要使用与Actors不同的并发模型
系统示例:计划的事务批处理系统
根据相关评论进行编辑
我假设OP与Akka和Message Queues都可以处理的分布式处理有关。那就是我以为他在谈论分布式Akka。与大多数消息队列相比,使用Akka进行本地并发是一个不二之选。我之所以这么说是因为您可以在本地将消息队列模型作为并发模型(即,主题,队列,交换)应用,而Reactor库和简单反应都可以这样做。
选择正确的并发模型/库对于低延迟应用程序非常重要。诸如消息队列之类的分布式处理解决方案通常并不理想,因为路由几乎总是通过有线方式完成,这显然比应用程序内部的速度慢,因此Akka将是一个更好的选择。但是,我相信某些专有的MQ技术可以进行本地路由。就像我前面提到的,大多数MQ客户端对线程非常愚蠢,不依赖非阻塞IO,并且每个连接/队列/通道都有一个线程...具有讽刺意味的是,非阻塞io并不总是低延迟,但通常资源更多高效。
如您所见,分布式编程和并发编程的主题很大,并且每天都在变化,因此我的初衷不是混淆,而是专注于分布式消息处理的一个特定领域,尽管我是OP所关心的。在并发方面,人们可能希望将搜索的重点放在“反应性”编程(RFP /流)上,这是“较新的”但与参与者模型和消息队列模型相似的模型,所有这些模型通常可以组合在一起,因为它们基于事件。