当前位置: 首页 > 面试题库 >

高性能JMS消息传递

傅胡媚
2023-03-14
问题内容

我阅读了今年的UberConf的幻灯片,其中一位发言者认为Spring
JMS给您的消息队列系统增加了性能开销,但是在幻灯片中我看不到任何证据支持这一点。演讲者还提出了点对点比传统“发布-
订阅”方法更快的情况,因为每个消息仅发送一次,而不是广播给每个消费者。

我想知道是否有经验的Java消息传递专家可以在这里介绍一些技术问题:

  • 使用Spring JMS而不是单纯的JMS实际上会产生性能开销吗?如果是这样,将在哪里引入?有什么办法解决吗?
  • 有什么实际证据支持P2P比pub-sub模型更快,如果是这样,那么在任何情况下您都想通过P2P进行pub-sub(即 为什么要慢一些?!? )?

问题答案:

1)首先,Spring JMS的开销是使用JmsTemplate通过下面的缓存机制发送消息。本质上,JmsTemplate将对您发送的每条消息执行以下操作:

  • 建立连接
  • 建立工作阶段
  • 创建生产者
  • 建立讯息
  • 发信息
  • 闭幕会议
  • 紧密连接

可以将此与可以重用事物的手动编写的代码进行比较:

  • 建立连接
  • 建立工作阶段
  • 创建生产者
  • 建立讯息
  • 发信息
  • 建立讯息
  • 发信息
  • 建立讯息
  • 发信息
  • 闭幕会议
  • 紧密连接

由于创建连接,会话和生产者需要在客户端和JMS提供者之间进行通信,并且当然需要进行资源分配,因此它将为许多小消息带来相当大的开销。

您可以通过缓存JMS资源来轻松解决此问题。例如,使用spring
CachingConnectionFactory或ActiveMQs
PooledConnectionFactory(如果使用的是ActiveMQ,则将其标记为该问题)。

如果您在完整的JavaEE容器中运行,则在检索JNDI连接工厂时通常会内置并隐含池/缓存。

使用Spring默认消息侦听容器进行接收时,spring的薄层可能增加很少的开销,但是主要方面是可以在并发性等方面调整性能。本文对此进行了很好的说明。

2)

PubSub是一种使用模式,发布者无需知道存在哪些订阅者。您不能简单地用p2p来模仿它。而且,在手头没有任何证据的情况下,我会争辩说,如果您要将相同的消息从一个应用程序发送到其他十个应用程序,则发布-
订阅设置将比发送消息十倍p2p更快。

另一方面,如果您只有一个生产者和一个消费者,请选择带有队列的P2P模式,因为在某些方面它更易于管理。P2P(队列)允许负载平衡,而pub /
sub则不允许(很容易)。

ActiveMQ还具有混合版本VirtualDestinations-本质上是具有负载平衡的主题。

实际的实现因供应商的不同而有所不同,但是主题和队列在本质上并没有什么不同,并且应具有相似的性能。您应该检查的是:

  • 坚持不懈?(=较慢)
  • 消息选择器?(=较慢)
  • 并发?
  • 耐用的订户?(=较慢)
  • 请求/答复,与临时队列“同步”(=开销=较慢)
  • 队列预取(在某些方面影响性能)
  • 快取


 类似资料:
  • 此应用程序收到 但是,当不存在web套接字会话,并且JMSProducer将消息发送到QueueSenderSessionBean中的目标“jms/notificationQueue”时,消息会立即在NotificationEndpoint中使用。这不是我的意图。 我的目的是让队列保留消息,直到用户连接到NotificationEndpoint。如果用户没有连接到NotificationEndpo

  • spring XML中的jmsTemplate定义: 有人对问题有什么建议吗/关于如何实现延迟消息传递的其他想法?谢了!

  • 我正在读一条来自Solace的信息。我能够成功地阅读信息。假设我正在阅读一条消息,在侦听器线程上读取/处理消息时,应用程序崩溃。那我怎么能在那上面再读一遍那条信息呢。使用下面的代码,我无法再次阅读该消息。下面是我的配置

  • 我们有一个camel路由,在这里我们从输入队列读取消息,处理它,设置一些JMS头(使用exchange.getin().setheader(...)),然后将消息路由到某个输出队列。在MQ故障转移方案期间,将重新传递消息。但是,当重新传递消息时,我前面放置的JMS头丢失了。是否有任何方法可以在重新交付后保留JMS头?

  • 我对来自JMSMessageProperties类的“”头有问题,或者在我看来是这样,它导致了以下错误 我知道这是由于类中的变量造成的,下面的方法对此负责 和类ich捕获并将其记录为WARN 我知道这只是一个警告,但是我们希望保持日志干净,所以我们的想法是不要记录这个特定的WARN或尝试不传递。我已经基于创建了一个自定义映射器并使用它,但是正如你在starckTrace中看到的,默认映射器仍在使用

  • 我读到:http://www.javaworld.com/article/2074123/java-web-development/transaction-and-redelivery-in-jms.html?page=2 "通常,确认特定消息会确认会话接收的所有先前消息"(在客户端确认模式下) “邮件重新传递不是自动的,但在某些情况下会重新传递邮件” 我的问题是: 如何确保每次收到消息时都有一个