JMS 和 ThreadPool 问题?

问题描述 投票:0回答:2

我希望 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());

在主线程中 方式 1:

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
2个回答
0
投票

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

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

<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,该 bean 将它们打印到 stdout。


0
投票
为什么不直接使用 MDP?看起来您正在重新创建 Spring 功能。

MDP 示例:

public class MyMDP implements MessageListener { public void onMessage(Message message) { if (message instanceof TextMessage) { ...do whatever... } } }
    
© www.soinside.com 2019 - 2024. All rights reserved.