GlassFish работает EJB на разных физических серверах - PullRequest
3 голосов
/ 25 февраля 2012

У меня есть веб-приложение Java EE 6, работающее на GlassFish 3.1.Приложение использует 2 экземпляра локального Singleton EJB MySingleton.Каждый экземпляр MySingleton подключается к стороннему программному обеспечению через API.

MySingleton.java

@Singleton
@LocalBean
public class MySingleton { 
    @PersistenceContext private EntityManager em;    
    private ThirdPartyAPI thirdPartyAPI;
    ...
}

MySingletonManager.java

@Singleton
@LocalBean
public class MySingletonManager { 
    @EJB private MySingleton mySingletonA;
    @EJB private MySingleton mySingletonB;        ///Aargh! They can't run on the same server!!
    ...
}

Вот ограничения:

  1. сторонний поставщик программного обеспечения требует, чтобы его программное обеспечение запускало каждый экземпляр ThirdPartyAPI на другом физическом сервере
  2. MySingleton используетвнедренный экземпляр EntityManager, необходимый для запросов и транзакций на одном и том же PersistenceContext.

Чтобы выполнить ограничение 1, я думаю, что мне нужно получить удаленный доступ к Singleton EJB: мне потребуетсясказать серверу приложений что-то вроде «запустить mySingletonA на сервере A, mySingletonB на сервере B».Для этого я вижу, что есть возможность вызывать удаленный EJB через JNDI.

. Чтобы удовлетворить ограничение 2, я думаю, что мне нужно использовать GlassFish clustering, потому что PersitenceContext должен бытьобщий доступ для 2 экземпляров MySingleton.

К сожалению, я не могу найти никаких ссылок на то, как использовать 2 технологии вместе (удаленный EJB и кластеризация).

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

1 Ответ

2 голосов
/ 28 февраля 2012

Пара вещей ...

Во-первых, если вы подключаетесь к внешней системе EIS, «правильный» способ - написать JCA-адаптер и внедрить экземпляр с помощью @Resource. Их довольно просто написать, у Адама Бина есть хороший пример написания простого. Думайте о @Resource как о создании собственного источника данных для вашего приложения. Это на самом деле довольно весело, когда вы все это понимаете. Запись любого EJB-компонента, использующего сокеты или синхронизацию, технически не поддерживается спецификацией JEE6.

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

Но ... если вы действительно хотите делать сложные вещи с одноэлементными EJB-компонентами, вы, вероятно, могли бы сделать это вместо этого:

Во-первых, избавьтесь от MySingletonManager. Кластеризация прозрачна, вы не должны знать, что вы кластеризованы. Во-вторых, измените ваш одиночный код на:

@Singleton
@Remote
public class MySingleton { 
    @PersistenceContext private EntityManager em;    
    private ThirdPartyAPI thirdPartyAPI;
    ...

}

Важно понимать, что синглтон НЕ МОЖЕТ иметь состояние. Если ThirdPartyAPI удерживает состояние между вызовами, могут происходить забавные вещи. Вам также нужно будет установить декоратор кода соединения циклического перебора вокруг третьегоPartyAPI, чтобы он подключался к обоим вашим серверам ThirdPartyServers. Наконец, создайте кластер GlassFish и разверните свой EJB по всему кластеру. Вставьте его в свой код следующим образом:

@EJB MySingleton myIns;

Это автоматически найдет EJB-компонент где-то в вашем кластере и даст вам справку. Теперь предположим, что все это работает, и я ничего не пропустил, теперь у вас есть проблема с параллелизмом, поскольку по умолчанию доступ к любому EJB-компоненту сериализуется. Вы можете добавить @ConcurrencyAttribute (NO_LOCK), но EntityManager не является поточно-ориентированным и также транзакционным.

В целом, Singleton EJB вызовет у вас много проблем. Потратьте время на написание адаптера JCA!

...