23

我正在开发一个将大量使用 JBoss Messaging (JMS) 的项目。我的任务是为其他开发人员围绕消息构建一个易于使用的包装器,并且正在考虑使用 JMS 的消息选择器来提供一种过滤技术,以将不必要的消息发送降至最低。我很好奇是否有人在性能方面有这样做的经验?我担心 JMS 提供者可能会陷入消息选择器的困境,从而有效地破坏了整个目的。但是,这比为每种消息类型创建一长串主题/队列要好得多。

最终,毫无疑问,我最终会使用两者的某种组合,但无论我更倾向于哪种方式,我都会担心对性能的影响。

4

5 回答 5

20

正如 Martin 所提到的,默认情况下,大多数 JMS 实现将在客户端处理消息选择器,除非它们是持久订阅的一部分,此时大多数JMS 实现也会在服务器上处理它们,以避免在显着减少时保留太多消息通过选择器的消息数量。某些系统(如 SonicMQ)允许您指定应在服务器上处理消息选择器,这在您的消息代理上可用 CPU 过多但消费者上没有可用 CPU 的情况下是一个不错的选择。

请记住,虽然基于主题的选择通常更快,但它可能相当麻烦,因为如果你想听 5 个不同的东西,你必须有 5 个不同的 MessageConsumer。幼稚驱动程序实现中的每一个都是不同的线程,并且可以开始累加。出于这个原因,从发布中支持两者通常很有用,这样一些客户端可以只收听他们想要的主题,而其他客户端可以使用消息选择器(或代码-基于选择器)。

但是,您应该始终针对您的应用程序和您的代理进行测试。每个代理处理情况的方式不同,每个应用程序的功能也不同。您不能只说“始终使用技术 X”,因为用于客户端导向消息处理的每种技术都有不同的权衡。基准,基准,基准。

使用消息选择器要记住的一件事是它们不能动态更改,因此您可能会丢失消息或必须手动管理复杂的切换场景。想象以下用例:

  1. 您正在收听表单的消息选择器(Ticker in ('CSCO', 'MSFT'))
  2. 用户想开始收听 AAPL
  3. 您必须关闭旧的 MessageConsumer 并使用表单中的选择器启动一个新的 (Ticker in ('CSCO, 'MSFT', 'AAPL'))
  4. 在切换期间,您要么丢失消息(因为您在启动新消息之前关闭了旧消息),要么您必须手动删除重复消息(因为您在旧消息之前启动了新消息)
于 2009-03-23T14:22:12.750 回答
7

我的两分钱:

我问过自己关于 ActiveMQ 的完全相同的问题。

  • 首先,我没有使用选择器并创建了很多主题。性能很糟糕,因为没有大量资源,经纪人无法处理 100 个主题。
  • 然后我使用了主题/选择器的组合。我现在有少量主题。选择效果很好。但是负载不是很重,不超过10 msg/s

我确实开发了一个抽象层,允许开发人员在不问问题的情况下编写代码,我们通过切换实现来进行测试。

于 2009-03-26T10:52:51.230 回答
3

不同的实现,但我将传递我与 BEA 的 JMS 产品的高级架构师的对话。我提到了使用选择器,他评论了一些类似“很好,如果你不希望它执行”的内容。

我们的应用每秒发送 10 条消息。他可能已经习惯了看到每秒 100-1000 次的棘手问题。除非您处于更高的范围或硬件非常慢,否则许多队列/主题或选择器可能会正常工作。

关于 Don 关于 JMS 易于使用的观点……我们使用包装器来抽象事物。一旦遇到诸如健壮的重新连接和正确处理多线程/异步侦听器之类的问题,就会有许多错误的方法来编写代码。对我们来说,包装细节是非常值得的,这样客户就可以对大部分细节保持无辜。

于 2009-02-25T22:22:25.797 回答
3

根据我对 JBoss MQ 实现的经验,客户端使用消息选择器来过滤消息。显然,这意味着主题中的每条消息仍然会发送给每个收件人,即使他们忽略它。另一方面,服务器上不同的队列和主题会影响服务器性能。

我想说选择器的扩散会影响客户端和网络负载,而主题和队列的扩散会影响服务器负载。显然,网络负载、消息消费者负载和消息生产者负载的规模都不同。

除了简单的情况外,包装器变得棘手;我建议您将错误处理和 JMS API 包装到一个简单的消息传递 API 中,该 API 的概念结构可以满足您的特定需求。然后,在幕后,您可以毫不费力地更改为上述任何不同的设计。

于 2009-02-25T23:13:31.553 回答
2

嗯,我有疑问。JMS 非常易于使用。我已经看到这种尝试,并且更易于使用的解决方案更难使用和错误。

于 2009-02-25T21:25:11.877 回答