【问题标题】:How to use multiple sessions per connection in a multi-threaded application?如何在多线程应用程序中为每个连接使用多个会话?
【发布时间】:2016-05-19 19:05:28
【问题描述】:

假设我有一个连接c 和许多会话对象s1s2 ..sn,每个都在不同的线程中工作t1t2 ...tn

                                      c
                                      |
                -------------------------------------------------
                |          |          |                         |
             (t1,s1)    (t2,s2)    (t3,s3)      ......       (tn,sn)

现在假设一个线程t3 想要向特定队列q3 发送一条消息,然后异步收听回复。所以它做了以下事情:

 1:   c.stop();

 2:   auto producer = s3.createProducer(s3.createQueue(q3));
 3:   auto text = s3.createTextMessage(message);
 4:   auto replyQueue = s3.createTemporaryQueue();
 5:   text.setJMSReplyTo(replyQueue);
 6:   producer.send(text);

 7:   auto consumer = s3.createConsumer(replyQueue);
 8:   consumer.setMessageListener(myListener);

 9:   c.start();

之所以我在开头调用c.stop(),最后调用c.start(),是因为我确定是否有任何其他线程在连接上调用了start (使 所有 会话异步 - 对吗?)并且根据 the documentation:

"如果必须在异步会话上进行同步调用,例如创建消费者或生产者,则必须调用 Connection.Stop。可以通过调用 来恢复会话>Connection.Start 方法开始传递消息。”

所以在步骤开始时调用stop,最后调用start 似乎是合理的,因此代码似乎是正确的(至少对我而言)。但是,当我仔细考虑时,我认为代码有问题,因为它不能确保在t3 完成所有步骤之前没有其他线程调用start

所以我的问题是:

  • 我需要使用互斥锁来确保它吗?还是 XMS 自动处理它(这意味着我的推理是错误的)?
  • 如何设计我的应用程序,这样我就不必每次想异步发送消息和收听回复时都调用stopstart
  • 根据上面引用的文字,如果连接处于异步模式,我无法调用createProducer()createConsumer()。还有哪些我不能调用的方法?文档没有以这种方式对方法进行分类:

此外,文档没有明确说明是什么使会话异步。它说this

“通过将消息侦听器分配给消费者,不会使会话异步。仅当调用 Connection.Start 方法时,会话才会变为异步。”

我在这里看到两个问题:

  • 调用 c.start() 会使 所有 个会话异步,而不仅仅是一个。
  • 如果我调用c.start() 但没有为消费者分配任何消息侦听器,会话是否仍然是异步的?

我似乎有很多问题,所以如果有人能提供指向文档的部分或部分的链接,这些部分或部分解释了 XMS 对象的详细信息,那就太好了。

This 说,

"根据规范,在 Connection 上调用 stop()、close()、在 Session 上调用 setMessageListener() 等必须等到所有消息处理完成,即直到所有已输入的 onMessage() 调用退出。因此,如果有人试图在 onMessage() 中执行该操作,那么设计上就会出现死锁。”

但我不确定该信息是否真实,因为我没有在 IBM 文档中找到该信息。

【问题讨论】:

    标签: jms ibm-mq xms jms-session


    【解决方案1】:

    我更喜欢 KIS 规则。为什么不使用每个线程 1 个连接?因此,代码不必担心线程之间的冲突。

    【讨论】:

    • 为什么我不每个线程使用一个连接?嗯,可能有这种情况:假设主服务器需要与许多工作服务器通信,那么如果我每个线程使用一个连接,我可能会结束使用 N 个连接(对于 large、20、30 甚至更多的某些定义,N 可能足够大以至于不可行或不切实际)。此外,如果一个线程不经常使用一个连接,那么如果这个连接在多个线程之间共享​​>以获得资源的最大收益,这似乎是一个更好的策略。
    • 你不是很了解MQ。我有超过 10,000 个客户端连接的队列管理器,并且队列管理器执行没有问题。你的“大”什么都不是。几年前,我编写了一个名为 AQOL 的辅助应用程序,它默认为 8 个线程(每个线程 1 个连接)。我已经用 100 个线程对其进行了测试,没有问题。我在这里写过它:capitalware.com/rl_blog/?p=1385 注意:我有 20 多年的时间为 MQ 创建应用程序。所以,正如我所说,每个线程 1 个连接是一个更好的解决方案,但是嘿,如果你想构建一个过于复杂的系统,我无法阻止你。
    • 哇.. 这似乎非常真实。现在我有另一个小问题:我是否可以期望连接在几周/几个月内保持打开(并且有效)?或者我需要在发送每条消息之前检查它的状态(如果是,怎么做)?另外,创建会话/生产者/消费者/目的地是否昂贵?如果我太频繁地创建它们会是个好主意,比如每条消息都创建它们吗?或尽可能重复使用它们?
    • 没有调用来检查连接是否仍然有效/活动。只需使用 MQ 中的重新连接逻辑即可。 MQ 中最昂贵的调用是 MQCONN/X(即 JMS 的 createQueueConnection())。绝对不要每条消息做 1 个连接,而是重用连接/会话。
    猜你喜欢
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 2015-06-28
    • 2012-08-14
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多