2012-04-20 3 views
1

Я использую jboss5.1, EJB3.0 и автономное приложение Java, как «абонент»Раствор для Thread.sleep внутри EJB

У меня есть механизм, который публиковать сообщения через JMS тема для абонентов. , когда абонент получает сообщение, ему нужно выполнить несколько операций, пока он не начнет снова прослушивать будущие сообщения.

проблема заключается в том, что если абонент получит сообщение от темы ему необходимо будет получить достаточно назад быстро для прослушивания дальнейших сообщений (иначе он будет не хватать его в случае еще одно сообщение будет опубликовано)

Итак, мое решение - putThread.sleep() в течение нескольких секунд в издателе ejb.

Таким образом, убедитесь, что все подписчики вернулись, чтобы прослушать, прежде чем будет опубликовано новое сообщение.

Я знаю, что использование Thread внутри EJB'S не рекомендуется.

любое решение для этого сценария?

спасибо, луч.

+1

Что вы подразумеваете под «Это будет скучать по нему?» Похоже, у вас проблемы с дизайном, когда вы говорите: «ему нужно будет вернуться достаточно быстро, чтобы ...». Вы почти никогда не можете полагаться на то, что выполнение некоторого кода будет достаточно быстрым. Он должен работать, если требуется 1 мс или 1 час –

+0

Я думаю, вы правы. как бы вы переделали его таким образом, чтобы абонент получал сообщения все время? – rayman

+1

Извините, я не эксперт JMS, поэтому я не знаю, как это работает и какую гипотезу вы можете сделать. Я действительно не понимаю, почему вы пропустили бы какое-либо сообщение. Если вы заняты чем-то другим, сообщение должно быть поставлено в очередь, но не отбрасываться. Вы имеете в виду, что ваш абонент перестает слушать новые сообщения, когда они обрабатывают входящее сообщение, и они начинают снова слушать, когда они будут сделаны? –

ответ

1

ОК, так что ваша проблема на самом деле, что вы прекращаете прислушиваясь к очереди JMS при обработке сообщения, а затем вы регистрируетесь. Конечно, вы могли бы пропустить сообщения во время обработки предыдущего.

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

Например, если раньше у вас было что-то вроде этого:

public void onNewJMSMessage(JMSMessage message) { 
    unregisterMySelf(); 
    processMessage(message); 
    registerMySelf(); 
} 

Используйте вместо этого:

Инициация член класса, как это:

private ExecutorsService processingPool = Executors.newSingleThreadExecutor(); 

и

public void onNewJMSMessage(final JMSMessage message) { 
    processingPool.submit(new Runnable() { 

     @Override 
     public void run() { 
       processMessage(message); 
     } 
    }); 
} 

Thi s гарантирует, что обрабатывается только одно сообщение (если класс-оболочка уникален, в противном случае вам нужно будет настроить одноэлементный режим, чтобы обеспечить уникальность пула однопоточных потоков).

Сделав это, это позволит вам удалить этот Thread.sleep в ваш EJB, который является злом и источником всех головных болей.

+0

Это может вызвать значительное увеличение потребления памяти. Все сообщения могут быть потеряны, если OutOfMemoryerror появляется. Вместо этого я бы предложил постоянный queu/topic. (-1) –

+0

@ckuetbach У меня недостаточно контекста, чтобы знать, насколько важны важные сообщения, и я не знаю, как большие сообщения и сколько он получает. В нем говорится, что у него есть отдельное приложение, поэтому для меня вне приложений JEE у вас может быть программное обеспечение без гражданства, которое является только клиентом, который может потерять или пропустить некоторые сообщения при их выключении (охотно или нет). Если бы он каким-то образом ранее правильно хранил сообщения, он мог бы, конечно, восстановить это. –

+0

Да, вы правы, вопрос не совсем точный. –

2

IMHO, вам не нужно будет полностью отключать поток издателя. По определению, при работе с JMS и ведомыми сообщениями, у вас есть гарантия, что сообщения будут доставлены. Единственное, что не гарантировано, это порядок: Message Driven Beans может получать сообщения в порядке, отличном от заказа, который они отправили.

Кроме того, весь смысл работы с JMS, чтобы позволить вам отправлять сообщения асинхронно (даже если вы действительно можете настроить очереди/тему работать синхронно)

0

Я знаю, что эта ветка устарела, но я вынужден добавить свои два цента. Я согласен с тем, что сказал Кию.

Согласно спецификациям EJB2, корпоративный компонент не должен управлять потоками. Я не знаю, что должны сказать последние спецификации, но я буду потрясен, если это будет изменено.

Дело в том, что JMS спроектирован таким образом, чтобы сообщения не терялись. Таким образом, MDB собирается потреблять сообщения, несмотря ни на что. Кроме того, следует помнить, что MDB (как и другие EJB) управляются контейнерами. Почему вы думаете, что только один экземпляр вашего MDB будет работать, чтобы потреблять ваши сообщения (если, конечно, вы не проектируете его таким образом, что, я уверен, не так).

Смежные вопросы