akka 何时使用Actor而不是消息传递解决方案(如WebSphere MQ或Tibco Renault)?

gwo2fgha  于 2023-10-18  发布在  其他
关注(0)|答案(4)|浏览(264)

我已经读过What design decisions would favour Scala's Actors instead of JMS?的问题和答案了。
通常,我们使用已经存在多年的消息传递解决方案:JMS实现(如WebSphere MQ或Apache ActiveMQ)用于点对点通信,或者Tibco Rendevous用于多播消息传递。
它们非常稳定,经过验证,并提供高可用性和性能。然而,配置和设置似乎比Akka复杂得多。
对于到目前为止已经成功使用了上述产品(WebSphere MQ或ActiveMQ)的某些用例,何时以及为什么应该使用Akka?为什么我应该在未来的项目中考虑使用Akka而不是WebSphere MQ或Tibco RV?
我什么时候应该避开 akka ?它是否提供与其他解决方案相同的高可用性和性能?或者,将Akka与其他消息传递中间件进行比较是一个坏主意?
除了JMS(点对点)、TibcoRV(多播)和Akka之外,我还应该考虑JVM环境中的另一种消息传递解决方案?

oipij1gg

oipij1gg1#

首先,“老”消息系统(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's remoting还是相当新的,可能仍然不能提供传统消息队列提供的所有可靠消息保证和QoS(但这每天都在变化)。它通常也是点对点的,但我认为它支持服务器到点对点,这通常是大多数MQ系统所做的(即单点故障),但也有MQ系统是点对点的(RabbitMQ是服务器到点对点的)。

**最后,RabbitMQ和Akka实际上是很好的一对。**你可以使用Akka作为RabbitMQ的 Package 器,特别是因为RabbitMQ不能帮助你处理消息的消费和本地路由消息(在单个JVM中)。
**何时选择 akka **

  • 有很多消费者(想想数百万)。
  • 需要低延迟
  • 对Actor并发模型开放
  • 示例系统:交互式真实的时间聊天系统 *
    何时选择MQ
  • 需要与许多不同的系统集成(即非JVM)
  • 消息可靠性比延迟更重要
  • 想要更多的工具和管理界面
  • 由于前面的几点更适合长时间运行的任务
  • 希望使用与Actor不同的并发模型
  • 示例系统:一个预定的事务批处理系统 *
    根据相关评论编辑

我假设OP关注的是Akka和消息队列都可以处理的分布式处理。我以为他说的是distributed Akka与大多数消息队列相比,使用Akka进行本地并发是一个苹果和橙子的对比。我说的最多是因为你可以在本地应用消息队列模型作为一个并发模型(即主题,队列,交换),Reactor库和simple-react都可以做到。
选择正确的并发模型/库对于低延迟应用程序非常重要。像消息队列这样的分布式处理解决方案通常并不理想,因为路由几乎总是通过线路完成的,这显然比应用程序内部慢,因此Akka将是一个上级选择。但是,我相信一些专有的MQ技术允许本地路由。另外,正如我前面提到的,大多数MQ客户端在线程方面都很愚蠢,不依赖于非阻塞IO,每个连接/队列/通道都有一个线程。具有讽刺意味的是,非阻塞IO并不总是低等待时间,而是通常更具资源效率。
正如你所看到的,分布式编程和并发编程的主题相当大,每天都在变化,所以我的初衷不是混淆,而是专注于分布式消息处理的一个特定领域,这是我认为OP所关注的。在并发性方面,人们可能希望将他们的搜索集中在“React式”编程(RFP /流)上,这是一种“较新”但与演员模型和消息队列模型相似的模型,所有这些模型通常可以组合在一起,因为它们是基于事件的。

展开查看全部
oiopk7p5

oiopk7p52#

我不是消息系统方面的Maven,但你可以在你的应用程序中将它们与Akka合并结合起来,两全其美。这里有一个例子,你可能会发现对Akka和消息传递系统的实验很有用,在这个例子中是ZeroMQ:
https://github.com/zcox/akka-zeromq-java

zwghvu4y

zwghvu4y3#

Akka-Camel是一个比ZeroMQ更好的例子- ZeroMQ是一个直接的tcp到tcp通信(因此为零-没有消息队列)。
使用AkkaCamel,您可以抽象出队列,并直接从actor生成/消费消息,而无需任何代码来处理消息队列消息推送/拉取。
您可以放弃akka-zeromq,直接使用Akka进行远程处理。我认为akka-zeromq正在从核心库中删除,但我们为akka构建了一个很好的zeromq库,名为scala-zeromq(https://github.com/mDialog/scala-zeromq
Akka有几个关键的核心用例:
1)可变状态
将共享状态隐藏在参与者中更容易处理共享状态。由于参与者同步处理消息,因此您可以在参与者中保存状态,并通过参与者API以高度一致性公开该字段
2)分布
并发在akka中是免费的,所以你说它实际上是为了解决分发问题。跨机器和内核的分布。Akka内置了“位置透明性”,用于通过线路发送消息。它还具有集群和模式,用于扩展单个服务。这使得它成为一个非常好的分发解决方案(例如微服务架构)
下面是一个使用Akka和ActiveMQ以及Akka-Camel(使用Java8)的示例

  1. import akka.actor.Props;
  2. import akka.camel.Camel;
  3. import akka.camel.CamelExtension;
  4. import akka.testkit.TestActorRef;
  5. import akka.testkit.TestProbe;
  6. import org.junit.Ignore;
  7. import org.junit.Test;
  8. import akka.camel.javaapi.UntypedProducerActor;
  9. import akka.camel.javaapi.UntypedConsumerActor;
  10. import static com.rogers.totes.TotesTestFixtures.*;
  11. import org.apache.activemq.camel.component.*;
  12. public class MessagingTest {
  13. @Test @Ignore
  14. public void itShouldStoreAMessage() throws Exception{
  15. String amqUrl = "nio://localhost:61616";
  16. Camel camel = (Camel) CamelExtension.apply(system);
  17. camel.context().addComponent("activemq", ActiveMQComponent.activeMQComponent(amqUrl));
  18. TestProbe probe = TestProbe.apply(system);
  19. TestActorRef producer = TestActorRef.create(system, Props.create((Producer.class)));
  20. TestActorRef consumer = TestActorRef.create(system, Props.create((Consumer.class)));
  21. producer.tell("Produce", probe.ref());
  22. Thread.sleep(1000);
  23. }
  24. }
  25. class Producer extends UntypedProducerActor{
  26. @Override
  27. public String getEndpointUri() {
  28. return "activemq:foo.bar";
  29. }
  30. }
  31. class Consumer extends UntypedConsumerActor{
  32. @Override
  33. public String getEndpointUri() {
  34. return "activemq:foo.bar";
  35. }
  36. @Override
  37. public void onReceive(Object message) throws Exception {
  38. System.out.println("GOT A MESSAGE!" + message);
  39. }
  40. }
展开查看全部
rlcwz9us

rlcwz9us4#

我不太了解上面提到的工具,但我熟悉底层的软件工程概念。所以我认为这一点依赖于一个单一的决策线索:分权我的意思是,除了所有XXX - MQ和Akka(作为消息传递架构组件)都可以为应用程序带来的分布之外,还有另一种称为分散化的能力。但是,由于在大多数用例中,去中心化和分布可以相互简化,因此应该首先重新检查对您的用例的这种质疑的有效性。然后问问自己,在处理消息传递需求时,单例或对等基础中哪一种适合您的需求。
Akka在对等基础上完成这项工作,因此它提供了一个分散的解决方案,但其他提到的工具提供了集中的解决方案。作为一个明确的例子,考虑实现一个需要像比特币这样的消息传递架构的网络。Akka能够支持这样的用例,但其他提到的工具将失败。所有其他提到的工具也支持消息传递架构,但除了Akka之外,没有一个可以支持比特币的去中心化要求。

相关问题