何时使用参与者代替诸如WebSphere MQ或Tibco Rendezvous之类的消息传递解决方案?

2020/11/30 22:31 · java ·  · 0评论

我已经阅读了以下问题和答案:哪些设计决策会更适合Scala的Actors而不是JMS?

通常,我们使用已经存在多年的消息传递解决方案:将诸如WebSphere MQ或Apache ActiveMQ之类的JMS实现用于点对点通信,或者将Tibco Rendevous用于多播消息传递。

它们非常稳定,经过验证,并提供高可用性和高性能。但是,配置和设置似乎比Akka复杂得多。

在迄今已成功使用上述产品(WebSphere MQ或ActiveMQ)的某些用例中,何时以及为何使用Akka?为什么在我的未来项目中应该考虑使用Akka代替WebSphere MQ或Tibco RV?

我什么时候应该避免Akka?它是否提供与其他解决方案相同的高可用性和性能?还是将Akka与其他消息传递中间件进行比较是一个坏主意吗?

也许除了JMS(点对点),TibcoRV(多播)和Akka之外,我还应该考虑JVM环境中的另一种消息传递解决方案?

首先,“较旧的”消息系统(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 /流)上,这是“较新的”但与参与者模型和消息队列模型相似的模型,所有这些模型通常可以组合在一起,因为它们基于事件。

我不是邮件系统方面的专家,但是您可以在应用程序中将它们与Akka结合使用,从而实现两全​​其美。这是一个示例,可能对尝试Akka和消息传递系统(在本例中为ZeroMQ)有用:

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

与ZeroMQ相比,Akka-Camel将是一个更好的示例-ZeroMQ是直接的tcp到tcp通讯(因此为零-没有消息队列)。

使用AkkaCamel,您可以抽象出队列并直接从actor生成/使用消息,而无需任何代码来处理消息队列消息的推/拉。

您可以放弃akka-zeromq并直接在远程处理中使用Akka。我认为akka-zeromq已从核心库中删除,但是我们为akka建立了一个很好的zeromq库,名为scala-zeromq(https://github.com/mDialog/scala-zeromq

Akka有几个关键的核心用例:

1)可变状态

通过将共享状态隐藏在actor中,可以更轻松地处理共享状态。当角色同步处理消息时,您可以在角色中保持状态并通过角色API高度公开地显示该字段

2)发行

并发在akka中是免费的,所以您说它实际上是在解决分发问题。跨机器和核心分布。Akka具有内置的“位置透明性”,可以通过网络发送消息。它还具有集群和模式,可用于扩展单个服务。这使其成为一个很好的分发解决方案(例如,微服务架构)

这是将Akka与ActiveMQ和Akka-Camel一起使用的示例(使用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);

    }
}
本文地址:http://java.askforanswer.com/heshishiyongcanyuzhedaitizhuruwebsphere-mqhuotibco-rendezvouszhileidexiaoxichuandijiejuefangan.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!