Проблема с JMS и ThreadPool? - PullRequest
0 голосов
/ 28 июля 2011

Я хочу, чтобы jms получал сообщение, когда один поток обработал сообщение (threadPool отправляет вызываемый объект). Сообщения принимаются главным потоком. Какой способ лучше ниже:

Я использую пружину 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);

Ответы [ 2 ]

0 голосов
/ 28 июля 2011

Почему вы просто не используете MDP?Похоже, вы воссоздаете функциональность Spring.

Пример MDP:

public class MyMDP implements MessageListener {
    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            ...do whatever...
        }
    }
}
0 голосов
/ 28 июля 2011

Я не уверен, что понимаю, что вы пытаетесь сделать.Если вы пытаетесь обрабатывать несколько сообщений одновременно, отойдите от JmsTemplate и используйте DefaultMessageListenerContainer с concurrentConsumers .Также доступно через пространство имен JMS .

Например, кажется, что вы можете выбросить весь код, который вы показываете в своем вопросе, и использовать его вместо этого:

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

Это автоматически создаст до 10 потоков для одновременной обработки сообщений.Когда приходит сообщение, оно будет использовать один из рабочих потоков для вызова fooService.handleNewFoo (), где fooService - это bean-компонент в контексте Spring.пример проекта на 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.Существует также прослушиватель сообщений Spring, как я описал выше, который принимает сообщения и передает их тому же компоненту, который создает сообщения, который выводит их на стандартный вывод.

...