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