何时使用参与者而不是消息传递解决方案(例如 WebSphere MQ 或 Tibco Rendezvous)?

发布于 2024-11-02 05:06:05 字数 557 浏览 1 评论 0原文

我已经阅读了 哪些设计决策将有利于 Scala 的 Actor 而不是 JMS? 的问题和答案。

通常,我们使用已经存在多年的消息传递解决方案:要么使用 WebSphere MQ 或 Apache ActiveMQ 等 JMS 实现来进行点对点通信,要么使用 Tibco Rendevous 进行多播消息传递。

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

对于到目前为止已成功使用上述产品(WebSphere MQ 或 ActiveMQ)的某些用例,我何时以及为什么应该使用 Akka?为什么我应该考虑在未来的项目中使用 Akka 而不是 WebSphere MQ 或 Tibco RV?

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

美男兮 2024-11-09 05:06:05

首先,“较旧”的消息系统 (MQ) 在实现上较旧,但在工程理念上却较新:事务持久队列。 Scala Actors 和 Akka 可能是较新的实现,但构建在较旧的 Actors 并发模型上。

然而,这两个模型在实践中最终非常相似,因为它们都是基于事件消息的:请参阅我对 RabbitMQ 与 Akka 的回答。

如果您只想为 JVM 编写代码,那么 Akka 可能是一个不错的选择。否则我会使用 RabbitMQ。

另外,如果您是 Scala 开发人员,那么 Akka 应该是理所当然的选择。然而,Akka 的 Java 绑定不太像 Java,并且由于 Scala 的类型系统而需要强制转换。

另外,在 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)集成
  • 消息可靠性比延迟更重要
  • 想要更多的工具和管理 UI
  • 因为前面的观点更适合长时间运行的任务
  • 想要使用与 Actor 不同的并发模型

示例系统:计划的事务批处理系统

根据相关评论进行编辑

我假设OP与分布式处理有关,Akka 和消息队列都可以处理。我假设他正在谈论分布式 Akka使用 Akka 实现本地并发与大多数消息队列相比简直就是苹果与橘子的比较。我说最多是因为您可以在本地将消息队列模型应用为并发模型(即主题、队列、交换),其中 Reactor 库和 simple-react 执行此操作。

选择正确的并发模型/库对于低延迟应用程序非常重要。诸如消息队列之类的分布式处理解决方案通常并不理想,因为路由几乎总是通过线路完成,这显然比应用程序内慢,因此 Akka 将是一个更好的选择。不过,我相信一些专有的 MQ 技术允许本地路由。另外,正如我之前提到的,大多数 MQ 客户端对于线程处理非常愚蠢,并且不依赖非阻塞 IO,并且每个连接/队列/通道都有一个线程...具有讽刺意味的是,非阻塞 io 并不总是低延迟,但通常需要更多资源高效的。

正如你所看到的,分布式编程和并发编程的主题相当大,并且每天都在变化,所以我的初衷并不是混淆,而是专注于分布式消息处理的一个特定领域,这也是我认为OP所关心的。在并发性方面,人们可能希望将搜索集中在“反应式”编程(RFP/流)上,这是一种“较新”但与参与者模型和消息队列模型类似的模型,所有这些模型通常都可以组合起来,因为它们是基于事件的。

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.

微凉徒眸意 2024-11-09 05:06:05

我不是消息传递系统方面的专家,但您可以在应用程序中将它们与 Akka 结合起来,从而两全其美。下面是一个示例,您可能会发现对于尝试 Akka 和消息传递系统很有用,在本例中为 ZeroMQ:

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

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

寂寞清仓 2024-11-09 05:06:05

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)可变状态

通过将共享状态隐藏在 Actor 中,可以更轻松地处理共享状态。由于 Actor 同步处理消息,您可以在 Actor 中保存状态,并通过 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);

    }
}

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);

    }
}
过潦 2024-11-09 05:06:05

我不太了解提到的工具,但我熟悉底层的软件工程概念。所以我认为这一点依赖于一个单一的决策线索:去中心化。我的意思是,除了所有 XXX - MQ 和 Akka(作为消息传递架构组件)可以为您的应用程序带来的分布之外,还有另一种称为去中心化的功能。但由于在大多数用例中,去中心化和分布可以相互简化,因此应首先重新检查对您的案例提出的此类质疑的有效性。然后问问自己,处理消息传递要求时,单例或点对点基础上的哪一个更适合您的需求。

Akka 在点对点的基础上完成这项工作,因此它提供了分散的解决方案,但其他提到的工具提供了集中的解决方案。作为一个澄清的例子,考虑实现一个需要像比特币这样的消息传递架构的网络。 Akka 能够支持此类用例,但其他提到的工具将失败。所有其他提到的工具也都支持消息传递架构,但除了 Akka 之外,没有一个工具可以支持比特币的去中心化要求。

I do not know mentioned tools very well, but I'm familiar with the underlying software engineering concepts. So I think the point relies on a single decision clue: decentralization. I mean other than distribution which all XXX - MQ and Akka (as message passing architecture components) can bring to your application there is another capability called decentralization. But since in most use cases decentralization and distribution can be reduced to each other, the validity of such questioning on your case shall be first rechecked. Then ask yourself, handling the message passing requirement on which of the singleton or peer-2-peer basis suits your needs.

Akka does the job on a peer-2-peer basis so it offers a decentralized solution, but other mentioned tools offer centralized solutions. As a clarifying example think of implementing a network which require message passing architecture like Bitcoin. Akka is capable to support such use case, but other mentioned tools will fail. All other mentioned tools support message passing architecture as well, but none can support decentralization requirements of Bitcoin except Akka.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文