【问题标题】:JMS Client Session UsageJMS 客户端会话使用
【发布时间】:2012-06-15 04:12:12
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: java .net jms websocket kaazing


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 感谢您的回答,但您并没有真正解决我的问题。我不明白何时以及如何创建 sessions - 并发处理收到的消息不是我的问题。我目前的方法是创建一个单一的、长期存在的、非事务性的会话,从中创建所有消费者。然后,对于我需要发送的每条消息,我都会创建一个用于发送消息的短期事务会话。这似乎有效,但也似乎相当复杂。你能评论我的方法吗?
    猜你喜欢
    • 1970-01-01
    • 2011-06-14
    • 2017-04-01
    • 1970-01-01
    • 2015-01-08
    • 2013-12-01
    • 2013-06-01
    • 2018-04-27
    相关资源
    最近更新 更多