2

我正在尝试利用 .NET Kaazing 客户端通过 Web 套接字与 JMS 后端进行交互。我正在努力理解会话的正确用法。最初,我有一个跨所有线程共享的会话,但我注意到这不受支持

Session 对象是用于产生和使用消息的单线程上下文。尽管它可以在 Java 虚拟机 (JVM) 之外分配提供者资源,但它被视为轻量级 JMS 对象。

我只有一个会话的原因只是因为我认为这会产生更好的性能。由于文档声称会话是轻量级的,我毫不犹豫地切换我的代码以使用每个“操作”的会话。“操作”是指发送单个消息或订阅队列/主题。在前一种情况下,会话是短暂的,并在消息发送后立即关闭。在后一种情况下,只要订阅处于活动状态,会话就需要存在。

当我尝试创建多个会话时,出现错误:

System.NotSupportedException: Only one non-transacted session can be active at a time

谷歌搜索这个错误没有结果,所以我尝试切换到事务会话。但是当试图创建一个消费者时,我得到一个不同的错误:

System.NotSupportedException: This operation is not supported in transacted sessions

所以看起来我被困在一块石头和一个坚硬的地方之间。我看到的唯一可能的选择是跨线程共享我的会话,或者使用单个非事务会话来创建消费者,并使用多个事务会话来创建其他所有会话。这两种方法对我来说似乎都有些不合时宜。

任何人都可以阐明我在客户中处理会话的正确方法吗?

4

1 回答 1

0

有几种方法可以为您的应用程序添加并发性。您可以使用多个连接,但由于网络开销的增加,这可能是不可取的。更好的做法是实现一个简单的机制,通过调度任务或通过 ConcurrentQueues 传递消息来处理消息侦听器中的并发。以下是一些实施策略的选择:

  1. 基于任务的方法将使用 TaskScheduler。在 MessageListener 中,将安排一个任务来处理工作并立即返回。例如,您可以为每条消息安排一个新任务。此时,MessageListener 将返回,并且下一条消息将立即可用。这种方法适用于低吞吐量应用程序 - 例如每秒处理几条消息 - 但您可能需要并发性,因为某些消息可能需要很长时间才能处理。

  2. 另一种方法是使用消息的数据结构来处理待处理的工作(ConcurrentQueue)。当调用 MessageListener 时,每个 Message 都会被添加到 ConcurrentQueue 并立即返回。然后,一组单独的线程/任务可以使用适合您的应用程序的策略从该 ConcurrectQueue 中提取消息。这将适用于更高性能的应用程序。

  3. 这种方法的一种变体是为每个处理入站消息的线程设置一个 ConcurrentQueue。在这里,MessageListener 不会管理自己的 ConcurrentQueue,而是将消息传递到与每个线程关联的 ConcurrentQueue。例如,如果您有代表股票提要和新闻提要的入站消息,则一个线程(或一组线程)可以处理股票提要消息,另一个可以单独处理入站新闻项目。

请注意,如果您使用 JMS 队列,则当您的 MessageListener 返回时,每条消息都会被隐式确认。这可能是也可能不是您希望应用程序的行为。

对于更高性能的应用程序,您应该考虑方法 2 和 3。

于 2012-06-12T15:27:19.313 回答