Как лучше всего делиться экземплярами бизнес-объектов между веб-приложениями Java с помощью JBoss и Spring? - PullRequest
14 голосов
/ 06 ноября 2008

В настоящее время у нас есть веб-приложение, загружающее контекст приложения Spring, который создает стек бизнес-объектов, объектов DAO и Hibernate. Мы хотели бы поделиться этим стеком с другим веб-приложением, чтобы избежать нескольких экземпляров одних и тех же объектов.

Мы рассмотрели несколько подходов; экспонирование объектов с использованием JMX или JNDI или EJB3.

У разных подходов есть свои проблемы, и мы ищем легкий метод.

Есть предложения, как это решить?

Редактировать: я получил комментарии с просьбой немного уточнить, так что здесь:

Основная проблема, которую мы хотим решить, заключается в том, что мы хотим иметь только один экземпляр Hibernate. Это связано с проблемами с отключением кэша 2-го уровня Hibernate при запуске нескольких клиентских приложений, работающих с одним и тем же источником данных. Кроме того, бизнес-стек / DAO / Hibernate становится довольно большим, поэтому не имеет смысла дублировать его.

Сначала мы попытались выяснить, как один бизнес-уровень может быть представлен другим веб-приложениям, и Spring предлагает JMX-упаковку по цене небольшого количества XML. Однако нам не удалось связать сущности JMX с деревом JNDI, поэтому мы не смогли найти объекты в веб-приложениях.

Затем мы попытались связать бизнес-уровень непосредственно с JNDI. Хотя Spring не предлагал никакого метода для этого, использование JNDITemplate для их связывания также было тривиальным. Но это привело к нескольким новым проблемам: 1) Менеджер безопасности запрещает доступ к загрузчику классов RMI, поэтому клиенту не удалось, как только мы попытались вызвать методы на ресурсе JNDI. 2) Как только проблемы безопасности были решены, JBoss выдал IllegalArgumentException: объект не является экземпляром объявления класса. Немного чтения показывает, что нам нужны реализации заглушки для ресурсов JNDI, но это кажется большой проблемой (возможно, Spring может помочь нам?)

Мы еще не слишком изучили EJB, но после первых двух попыток мне интересно, возможно ли то, чего мы пытаемся достичь.

Подводя итог, что мы пытаемся достичь: один экземпляр JBoss, несколько веб-приложений, использующих один стек бизнес-объектов поверх слоя DAO и Hibernate.

С уважением,

Nils

Ответы [ 9 ]

5 голосов
/ 06 ноября 2008

Развернуты ли веб-приложения на одном сервере?

Я не могу говорить за Spring, но очень просто перенести вашу бизнес-логику на уровень EJB с помощью Session Beans.

Организация приложения проста. Логика переходит к сессионным компонентам, и эти сессионные компоненты объединяются в один jar-файл как артефакт Java EE с файлом ejb-jar.xml (в EJB3 это, вероятно, будет практически пусто).

Затем свяжите свои классы сущностей в отдельный файл JAR.

Далее вы создадите каждое веб-приложение в своем собственном файле WAR.

Наконец, все jar-файлы и wars объединяются в EAR Java EE со связанным файлом application.xml (опять же, это, вероятно, будет весьма минимальным, просто перечисляя jar-файлы в EAR).

Этот EAR развернут оптом на сервере приложений.

Каждая WAR фактически независима - свои собственные сеансы, собственные пути контекста и т. Д. Но они имеют общий EJB-компонент, поэтому у вас есть только один кэш 2-го уровня.

Вы также используете локальные ссылки и вызов семантики для связи с EJB, поскольку они находятся на одном сервере. Здесь нет необходимости удаленных звонков.

Я думаю, что это довольно хорошо решает проблему, с которой вы столкнулись, и это довольно просто в Java EE 5 с EJB 3.

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

4 голосов
/ 11 мая 2009

А как насчет весны parentContext? Проверьте эту статью:

http://springtips.blogspot.com/2007/06/using-shared-parent-application-context.html

3 голосов
/ 06 ноября 2008

Terracotta может подойти здесь (раскрытие: я разработчик для Terracotta). Terracotta прозрачно группирует объекты Java на уровне JVM и интегрируется как с Spring, так и с Hibernate. Это бесплатно и с открытым исходным кодом.

Как вы сказали, проблема более чем одного клиентского веб-приложения, использующего кэш L2, заключается в синхронизации этих кешей. С помощью Terracotta вы можете кластеризовать один кэш Hibernate L2. Каждый клиентский узел работает со своей копией этого кластерного кэша, и Terracotta поддерживает его синхронизацию. Эта ссылка объясняет больше.

Что касается ваших бизнес-объектов, вы можете использовать интеграцию Terracotta Spring для кластеризации ваших компонентов - каждое веб-приложение может совместно использовать экземпляры кластеризованных компонентов, а Terracotta прозрачно поддерживает синхронизированное состояние кластера.

2 голосов
/ 03 декабря 2008

Вам стоит взглянуть на справочное веб-приложение Terracotta - Examinator. Он содержит большинство компонентов, которые вы ищете, - Hibernate, JPA и Spring с серверной частью MySQL.

Он был предварительно настроен на масштабирование до 16 узлов, 20 000 одновременных пользователей.

Проверьте это здесь: http://reference.terracotta.org/examinator

2 голосов
/ 08 ноября 2008

На самом деле, если вы хотите легкое решение и вам не нужны транзакции или кластеризация, просто используйте поддержку Spring для RMI. Это позволяет удаленно выставлять бины Spring с помощью простых аннотаций в последних версиях. Смотри http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html.

1 голос
/ 11 мая 2009

Spring имеет точку интеграции, которая может вас заинтересовать: EJB 3 инъекционный нтерцептор . Это позволяет вам получать доступ к бобам из EJB.

1 голос
/ 11 ноября 2008

Спасибо за ваши ответы. Мы еще не совсем там, но мы попробовали несколько вещей сейчас и видим вещи более четко. Вот короткое обновление:

Решение, которое представляется наиболее жизнеспособным, - EJB. Однако это потребует некоторого количества изменений в нашем коде, поэтому мы не собираемся полностью реализовывать это решение прямо сейчас. Я почти удивлен, что нам не удалось найти какую-то функцию Spring, чтобы помочь нам здесь.

Мы также попробовали маршрут JNDI, который заканчивается необходимостью заглушки для всех общих интерфейсов. Это доставляет массу хлопот, учитывая, что все равно на одном сервере.

Вчера у нас был небольшой прорыв с JMX. Хотя JMX определенно не предназначен для такого использования, мы доказали, что это можно сделать - без изменений кода и минимального объема XML (большое спасибо Spring за MBeanExporter и MBeanProxyFactoryBean). Основными недостатками этого метода являются производительность и тот факт, что классы нашего домена должны совместно использоваться через папку server / lib JBoss. Т.е. нам нужно удалить некоторые зависимости из наших WAR и переместить их в server / lib, иначе мы получим ClassCastException, когда бизнес-уровень возвращает объекты из нашей собственной доменной модели. Я полностью понимаю, почему это происходит, но это не идеально для того, чего мы пытаемся достичь.

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

0 голосов
/ 06 ноября 2008

Я не совсем уверен, что вы пытаетесь решить; в конце дня у каждого jvm будут реплицированные экземпляры объектов или заглушки, представляющие объекты, существующие на другом (логическом) сервере.

Вы можете настроить третий сервер «бизнес-логики» с удаленным API-интерфейсом, который могут вызывать два веб-приложения. Типичным решением является использование EJB, но я думаю, что у Spring есть опции удаленного взаимодействия, встроенные в его стек.

Другой вариант - использовать некоторую форму архитектуры общего кэша ... которая будет синхронизировать изменения объектов между серверами, но у вас все еще есть два набора экземпляров.

0 голосов
/ 06 ноября 2008

Взгляните на JBossCache . Это позволяет вам легко обмениваться / копировать карты данных между несколькими экземплярами JVM (одинаковые или разные). Он прост в использовании и имеет множество параметров протокола проводного уровня (TCP, UDP Multicast и т. Д.).

...