【问题标题】:JMS and ThreadPool problem?JMS 和 ThreadPool 的问题?
【发布时间】:2011-10-15 01:00:02
【问题描述】:

我希望 jms 在一个线程处理了一条消息时收到一条消息(threadPool 提交一个可调用的)。 消息由主线程接收。 下面哪种方式更好:

我使用的是 spring 3.0.5:

ApplicationContext context = new ClassPathXmlApplicationContext(
        "application-context.xml");
jmsTemplate = (JmsTemplate) context.getBean("jmsTemplate");
destination = (Destination) context.getBean("destination");
_log4j.debug("ThreadSize in xml\t"
        + appConfig.getThumbCreatorThreadSize());

在主线程方式一:

while (countFlag < 0) {
    try {
        TextMessage msg = (TextMessage) jmsTemplate
                .receive(destination);
        // prehandle ,then give to sub workers.
        if (msg != null) {
            _log4j.debug("JMSMessageID:\t" + msg.getJMSMessageID()
                    + "\t" + msg.getText());
            IConsumer thumbConsumerImpl = null;
            thumbConsumerImpl = new ThumbConsumerTaskImpl(msg);
            Future<List<ThumbCreatorInfo>> result = threadPool
                    .submit((Callable<List<ThumbCreatorInfo>>) thumbConsumerImpl);
        }
    } catch (IllegalArgumentException e) {
        _log4j.warn(e.getMessage(), e);
    } catch (JMSException e) {
        _log4j.error("Please check the queue server!JMSException!", e);
    } catch (Exception e) {
        _log4j.error("", e);
    }
}

在主线程方式2:

    TextMessage msg = (TextMessage) jmsTemplate.receive(destination);
    do {
        try {
            // prehandle ,then give to sub workers.
            if (msg != null) {
                _log4j.debug("JMSMessageID:\t" + msg.getJMSMessageID()
                        + "\t" + msg.getText());
                IConsumer thumbConsumerImpl = null;
                thumbConsumerImpl = new ThumbConsumerTaskImpl(msg);
                Future<List<ThumbCreatorInfo>> result = threadPool
                        .submit((Callable<List<ThumbCreatorInfo>>) thumbConsumerImpl);
            }
            msg = (TextMessage) jmsTemplate.receive(destination);
        } catch (IllegalArgumentException e) {
            _log4j.warn(e.getMessage(), e);
        } catch (JMSException e) {
            _log4j.error("Please check the queue server!JMSException!", e);
        } catch (Exception e) {
            _log4j.error("", e);
        }
    } while (countFlag < 0);

【问题讨论】:

    标签: java spring jms threadpool activemq


    【解决方案1】:

    我不确定我明白你想要做什么。如果您尝试同时处理多条消息,请远离 JmsTemplate 并使用 DefaultMessageListenerContainerconcurrentConsumers。也可通过JMS namespace 获得。

    例如,您似乎可以丢弃您在问题中显示的所有代码并改用它:

    <jms:listener-container concurrency="10">
        <jms:listener destination="some.queue" ref="fooService" method="handleNewFoo"/>
    </jms:listener-container>
    

    这将自动产生多达 10 个线程用于并发消息处理。当消息进来时,它将使用其中一个工作线程调用 fooService.handleNewFoo(),其中 fooService 是 Spring 上下文中的一个 bean。

    编辑: 我在 github 上创建了一个示例项目,展示了基本的 Spring JMS 设置。您可以在https://github.com/zzantozz/testbed/tree/master/basic-spring-jms 浏览源代码,或者直接克隆并运行它:

    git clone git://github.com/zzantozz/testbed.git tmp
    cd tmp
    mvn compile exec:java -Dexec.mainClass=rds.jms.Main -pl basic-spring-jms
    

    有一个启动 JMS 代理并启动 Spring 的主类。当 Spring 启动时,它会初始化一个开始发送 JMS 消息的 bean。如上所述,还有一个 Spring 消息侦听器,它使用消息并将它们传递给产生消息的同一个 bean,后者将它们打印到标准输出。

    【讨论】:

    • 我的消费者只让一个线程调度。然后让子线程处理。
    • @user808032:是的,你似乎在重写 Spring 已经做过的东西。我更新了我的答案。看看吧。
    • 哦。那么,只有一个客户端连接有 10 个线程吗?谢谢!
    • 默认情况下,除非使用外部事务管理器,否则是的。将创建一个连接。该连接将用于创建单个会话。该会话将用于为 10 个指定线程中的每一个创建一个使用者。这是all tunable
    • 嗨瑞恩。我不熟悉。你能给我一个完整的例子到我的电子邮件linzuxiong1988@gmail.com吗?谢谢!
    【解决方案2】:

    您为什么不直接使用 MDP?好像您正在重新创建 Spring 功能。

    示例 MDP:

    public class MyMDP implements MessageListener {
        public void onMessage(Message message) {
            if (message instanceof TextMessage) {
                ...do whatever...
            }
        }
    }
    

    【讨论】:

    • 我不太了解 Spring JMS。
    • 我怎样才能确保给了许多消息子线程?代码应该像: new ThumbConsumerTaskImpl(jmsTemplate,destination);在子线程中:(TextMessage) jmsTemplate.receive(destination);和 MDP。
    • 你的想法太好了。 MDP 与 jmsTemplate 的关系如何?
    猜你喜欢
    • 2011-02-09
    • 2013-09-29
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2014-02-26
    • 1970-01-01
    • 2014-06-17
    相关资源
    最近更新 更多