Java EE: динамическое создание и удаление слушателей сокетов из модели предметной области

Я создаю приложение Java EE, которое позволяет пользователям добавлять / удалять таблицы socketinfo (хранящиеся в базе данных) из веб-интерфейса. Если пользователь разрешает "информацию о сокетах" через веб-интерфейс, сервер приложений должен создать прослушиватель сокетов для входящих пакетов и обработать данные. Если пользователь отключает или удаляет "socketinfo", прослушиватель сокета должен быть удален. Весь продукт должен содержаться в одном ухе и предпочтительно соответствовать требованиям. Вот некоторые подходы, которые я рассмотрел, но с которыми столкнулся:

  1. Создайте адаптер ресурсов JCA для сокетов и используйте MDB в качестве слушателей. Проблема, с которой я столкнулся, заключалась в том, что я не могу понять, как программно развертывать MDB для разных сокетов, когда пользователь добавляет их.

  2. Создайте ejb @ Singleton / @ Service, который управляет потоками демона с тщательной синхронизацией. Одноэлементный ejb может быть внедрен в бизнес-уровень, чтобы операции CRUD и манипуляции с сокетами происходили в правильном рабочем процессе. Проблема заключалась в том, что предполагаемое создание потоков из EJB-компонентов считается плохой практикой и не соответствует спецификации (даже если жизненный цикл синглтона правильно обрабатывается и имеются надлежащие механизмы синхронизации?).

  3. Поместите потоки в модель предметной области (еще один синглтон?) И пусть EJB-компоненты используют эту модель. Это был худший из них, поскольку серверы приложений, как правило, имеют несколько загрузчиков классов, меньше поддержки контейнеров в целом, плюс это страдает от всего, от чего 2. страдает.

Есть идеи, как правильно справиться с этой ситуацией в Java EE?

РЕДАКТИРОВАТЬ: расширение этого вопроса: предполагая, что я решу подойти к этой проблеме, как предлагает Эвернли в своем решении 3, что я получу, сделав это в JCA (с настраиваемым интерфейсом для добавления внутренних потоков), чего я бы не получил от ( хорошо продуманный) синглтон? Хотя создание адаптера ресурсов не выглядит чудовищной задачей, это не кажется полностью тривиальным и может занять немного времени (а другим разработчикам, возможно, даже сложнее).


person insipid    schedule 24.05.2011    source источник
comment
Правильно ли я это читаю - вы хотите создать прослушиватели сокетов, то есть ServerSockets во время выполнения из контейнера Java EE, а затем захватывать и обрабатывать данные, поступающие в сокеты, заранее определенным образом?   -  person Vineet Reynolds    schedule 24.05.2011


Ответы (2)


Ваш анализ кажется разумным, и вы правы, когда говорите, что не можете динамически развернуть MDB для соответствия JCA.

Еще несколько дизайнерских идей:

  • Вы могли бы написать коннектор JCA, который возвращает SocketConnections (в духе JMS), который вы могли бы использовать для чтения из сокета. Продолжая аналогию с JMS, MDB представляет MessageListener, в то время как вы бы открыли MessageConsumer.

  • Вы можете использовать периодический таймер для имитации потока. Вместо потока с циклом while у вас есть таймер, который перепланировал сам себя. Я использовал это для одного приложения, чтобы иметь фоновый процесс, и это сработало. Обратите внимание, что я также создавал потоки прямо из EJB для выполнения некоторых параллельных вычислений в другом приложении, и это тоже работало нормально. Но потоки, которые были недолговечными, и бизнес-метод в bean-компоненте будут ждать, пока все не будет завершено, так что это не было серьезным нарушением спецификации.

  • Еще один вариант заключается в том, чтобы соединитель JCA обрабатывал потоки и т. Д. И доставлял все сообщения в MDB. MDB будет получать данные вместе с информацией о «канале», которому данные соответствуют, например Порт Socket. Это похоже на мультиплексирование всего в одном MDB, который затем демультиплексирует данные. Ваш коннектор может предоставить дополнительный API для управления созданием потоков и т. Д., И этот интерфейс может быть внедрен в ваш EJB (аналогично ConnectionFactory). Ваш коннектор может предоставлять дополнительный API для управления созданием потоков и т. Д. Непонятно, но я надеюсь, что вы поняли идею. Если я прав, соединитель JCA может гарантировать синхронную доставку данных в MDB, по крайней мере, для каждого сокета, чтобы MDB обрабатывал данные в правильном порядке.

Я бы выбрал №3, если позволяет время разработки.

ИЗМЕНИТЬ

Этот выбор действительно отчасти является вопросом чистоты дизайна. Однако одна проблема с потоками, порождаемыми пользователями, заключается в том, что вы, очевидно, не можете использовать для них декларативные транзакции. Возможно, вы можете использовать UserTransaction для разграничения транзакции самостоятельно. Я не знаю, насколько хорошо вы можете использовать EntityManager в такой ветке. Если вы в основном обрабатываете данные и не используете много функций промежуточного программного обеспечения, вы можете создавать потоки самостоятельно. См. Другой мой ответ: Как можно EJB распараллеливает длительный процесс с интенсивной загрузкой процессора?. Другие вещи, которые приходят мне в голову (не знаю, проблематичны они или нет): менеджер безопасности может препятствовать созданию потока (?), А не создавать их как потоки демона могут помешать приложению. сервер от правильно выключенного (?). Обратите внимание, что я создавал потоки из ServeletContextListener при запуске, и это отлично сработало. Это уловка, которую часто используют, даже если она нарушает спецификации. То же самое может произойти и для «недавно» представленных singleton beans. Итак, если у вас мало времени, вы, конечно, можете попробовать свое предложение с одноэлементным bean-компонентом и посмотреть, что работает, а что нет.

person ewernli    schedule 24.05.2011
comment
Если бы вы могли подробнее объяснить, почему 3 (см. Редактирование вопроса), я был бы очень признателен. - person insipid; 24.05.2011
comment
Я забыл упомянуть, что я также написал коннектор JCA для входящих и исходящих сообщений, и он тоже работает нормально, но я согласен, требуется некоторое время, чтобы ознакомиться со спецификацией JCA. - person ewernli; 25.05.2011

Я почти уверен, что №2 - лучшее решение (и оно действительно). Я не смотрел спецификацию для новых EJB "Singleton", но я предполагаю, что потоки внутри них будут приемлемы (учитывая, что допустимо выполнять свою собственную синхронизацию внутри этих EJB). они были разработаны, чтобы упростить (ier) развертывание служб типа управления, что вы могли сделать ранее, используя JMX (хотя развертывание не было стандартизовано). внутри JMX mbean, безусловно, было бы приемлемо создать свой собственный поток management, , так что я перенесу это на Singleton ejbs.

сделал быстрый беглый обзор спецификации ejb 3.1, и я думаю, единственное допущение для Singleton - это управление параллелизмом, без потоков / сокетов. отчасти глупо. Я предполагаю, что они не являются полноценной заменой JMX mbean. Тем не менее, вы всегда можете использовать JMX mbean, хотя развертывание нестандартно. если вы используете jboss, то аннотация Service эквивалентна mbean JMX, в котором все должно быть разрешено (потоки, сокеты и т. д.).

person jtahlborn    schedule 24.05.2011
comment
Хороший момент по поводу синхронизации. Не уверен, что bean-компоненты @Singleton предназначены для управления а-ля JMX. Я бы сказал, что они являются альтернативой кешированию и использованию static полей, что все делают, но также нарушают спецификацию. Но, возможно, @Service в JBoss (он специфичен для JBoss, нет?) Немного отличается. Однако пользовательские потоки избегают управления транзакциями контейнера, что необходимо учитывать, см. Мою правку в моем ответе. - person ewernli; 25.05.2011