6

我在一个数据处理应用程序中工作,在该应用程序中,通过将多个工作单元放在消息驱动 bean (MDB) 的多个实例侦听的消息队列上来实现并发。除了以这种方式实现并发之外,我们没有任何特定理由使用消息传递基础架构和 MDB。

这让我想到为什么使用多个线程无法实现相同的效果。

所以我的问题是,在什么情况下可以使用异步消息传递(例如 JMS)作为多线程的替代方法来实现并发?使用一种方法相对于另一种方法有哪些优点/缺点。

4

6 回答 6

6

它不能用作多线程的替代方案,它是实现多线程的一种方式。这里有三种基本的解决方案:

  1. 您负责队列的两端;
  2. 您负责发送数据;或者
  3. 您有责任接收数据。

接收数据是这里的关键,因为如果没有某种形式的多线程/多处理,真的没有办法做到这一点,否则你一次只能处理一个请求。在没有多线程的情况下发送数据更为可行,但您只是将处理这些消息的责任推给了外部系统。所以它不是多线程的替代品。

在您使用消息驱动 bean 的情况下,容器正在为您创建和管理线程,因此它不是多线程的替代方案,您只是在使用其他人的实现。

于 2009-10-20T06:33:40.147 回答
5

还有两个我认为没有被提及的额外奖励:交易持久性

虽然它不是必需的并且通常不是默认配置,但 JMS 提供程序可以配置为持久保存消息并参与 XA 事务,而只需很少或没有代码更改。

于 2009-10-20T06:49:08.433 回答
4

实际上,在 EJB 容器中,没有其他选择,因为不允许您在 EJB 容器中创建自己的线程。JMS 正在为您完成所有这些工作,代价是通过队列处理器运行它。您还可以创建一个 Java 连接器,它与容器有更密切的关系(因此可以有线程),但它的工作量要大得多。

如果使用 JMS 队列的开销不会影响性能,那么它是最简单的解决方案。

于 2009-10-20T06:39:09.947 回答
3

性能方面的多线程应该比任何消息传递都快,因为您添加了一个带有消息传递的额外网络层。
由于没有通用对象,应用程序消息传递可帮助您避免锁定和数据共享问题。
从扩展的角度来看,消息传递要好得多,因为您可以通过配置消息服务而不是更改应用程序来在多个服务器上配置更多节点。

于 2009-10-20T06:35:55.310 回答
1

消息传递可以大大减少多线程应用程序中的错误数量,因为它降低了数据竞争的风险。它还简化了添加新线程的过程,而无需更改应用程序的其余部分。

虽然我认为 JMS 在这里被稍微滥用了。java.util.concurrent 的线程安全队列和类似jetlang的库可以为您提供更好的性能。

于 2009-10-20T06:37:08.797 回答
1

使用多线程,您可以通过共享 CPU 核心来实现并发。但是,如果您改用 JMS,您可以平衡负载并将任务委托给其他系统。例如,假设您的应用程序要求在完成某项任务时发送电子邮件。并且您想同时发送电子邮件。您可以拉一个线程并异步处理它。或者您可以使用 JMS 将此邮件发送任务委托给其他系统。在 jms 中可以配置接收器线程的数量。多个节点也可以监听相同的 JMS 队列来平衡负载。您可以根据应用程序使用更多应用程序,例如持久队列、事务管理队列。

简而言之,JMS 可以更好地替代多线程,这取决于应用程序架构

于 2019-01-28T12:39:45.790 回答