В более крупных системах, где обработка пользовательских запросов распределена, вам нужна какая-то координация кэша, в противном случае результаты могут быть неверными и / или пользовательский опыт будет плохим. В
системе Qualitas у меня есть внешнее веб-приложение Spring, которое отправляет сообщения AMQP брокеру, которые впоследствии выбираются по маршруту Apache Camel. У меня была проблема с кэшированием, потому что веб-приложение показывало старые данные. Чтобы исправить это, я решил использовать координацию распределенного кэша. Читайте ниже, чтобы узнать, как настроить и запустить координацию распределенного кэша с помощью EclipseLink JPA2. В конце статьи есть ссылка на рабочий пример.
Проблема и решение
Итак, в моем случае веб-приложения и приложения интеграции используют один и тот же уровень доступа к данным (JPA2 и EclipseLink). Но пока маршрут Apache Camel обновлял статусы с каждым успешно выполненным шагом, веб-приложение все еще показывало старые статусы. Я решил использовать координацию кэша EclipseLink через JMS (RMI и CORBA также поддерживаются). В идеале я бы использовал AMQP вместо JMS, но все же JMS — лучший выбор, чем RMI ?
необходимое условие
Вам нужен JMS-брокер. Мы все знаем, что ActiveMQ — лучший вариант, поэтому скачайте его отсюда:
http://activemq.apache.org/download.html . Ниже я использовал настройки по умолчанию, поэтому все, что вам нужно сделать, это просто запустить брокер ActiveMQ.
Обновление persistence.xml
Мне пришлось добавить следующие 3 строки в мой файл persistence.xml:
<property name="eclipselink.cache.coordination.protocol" value="jms" /> <property name="eclipselink.cache.coordination.jms.topic" value="jms/Qualitas.EclipseLinkCacheTopic" /> <property name="eclipselink.cache.coordination.jms.factory" value="jms/Qualitas.EclipseLinkCacheConnectionFactory" />
И это было все. Почти все, как и тогда, мне приходилось настраивать JNDI-контексты как для веб-приложений (легкий), так и для Apache Camel (не такой простой).
Настройка контекста JNDI в Jetty
Я использую Jetty 7.6. Сначала мне нужно было создать файл WEB-INF / jetty-env.xml и определить мои ресурсы:
<?xml version="1.0"?> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <New id="eclipseLinkCacheConnectionFactory" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg>jms/Qualitas.EclipseLinkCacheConnectionFactory</Arg> <Arg> <New class="org.apache.activemq.ActiveMQConnectionFactory"> <Arg>nio://localhost:61616</Arg> </New> </Arg> </New> <New id="eclipseLinkCacheTopic" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg>jms/Qualitas.EclipseLinkCacheTopic</Arg> <Arg> <New class="org.apache.activemq.command.ActiveMQTopic"> <Arg>Qualitas.EclipseLinkCacheTopic</Arg> </New> </Arg> </New> </Configure>
Затем мне пришлось добавить правильные сопоставления в мой файл web.xml:
<resource-ref> <res-ref-name>jms/Qualitas.EclipseLinkCacheConnectionFactory</res-ref-name> <res-type>javax.jms.QueueConnectionFactory</res-type> <res-auth>Container</res-auth> </resource-ref> <resource-env-ref> <resource-env-ref-name>jms/Qualitas.EclipseLinkCacheTopic</resource-env-ref-name> <resource-env-ref-type>javax.jms.Topic</resource-env-ref-type> </resource-env-ref>
Как и было обещано, настройка контекста JNDI в веб-приложении была простой. Чтобы убедиться, что это действительно работает, я запустил веб-приложение и открыл веб-консоль ActiveMQ. Я видел Qualitas.EclipseLinkCacheTopic и увидел одного активного потребителя.
Настройка JNDI в Apache Camel
Это заняло у меня некоторое время. Короче говоря, чтобы настроить JNDI и привязать к нему объекты, необходимо выполнить следующие действия:
1. Создать фабрику и тему. В своем конфигурационном файле Spring скопируйте и вставьте:
<amq:topic id="eclipseLinkCacheTopic" physicalName="Qualitas.EclipseLinkCacheTopic" /> <amq:connectionFactory id="eclipseLinkCacheConnectionFactory" brokerURL="nio://localhost:61616" />
2. Создайте контекст JNDI
. Сначала я хотел попробовать эталонную реализацию Sun (так как в Google есть много сайтов, ссылающихся на нее), но она больше не является частью JDK. Я также хотел попробовать Apache OpenEJB (так как я большой поклонник Apache Geronimo), но я был напуган всеми зависимостями, которые я видел в своей консоли. После некоторого поиска в Google я нашел легкую реализацию JNDI от … Jetty ? Вот как настроить Spring JndiTemplate с реализацией JNDI в Jetty:
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> <property name="environment"> <props> <prop key="java.naming.factory.initial">org.eclipse.jetty.jndi.InitialContextFactory</prop> <prop key="java.naming.factory.url.pkgs">org.eclipse.jetty.jndi</prop> </props> </property> </bean>
3. Связать фабрику соединений и тему с контекстом JNDI У
меня был каталог JNDI, затем мне пришлось связать фабрику соединений и тему с контекстом JNDI. Я написал довольно наивную реализацию с использованием автопроводки Spring (она была наивной, потому что она потерпела бы неудачу, когда было больше кандидатов на автопроводку, но для меня все было в порядке):
@Component public class JndiBinder { @Autowired private JndiTemplate jndiTemplate; @Autowired private ConnectionFactory eclipseLinkCacheConnectionFactory; @Autowired private Topic eclipseLinkCacheTopic; @PostConstruct protected void bindEclipseLinkCacheResources() throws NamingException { jndiTemplate.bind("jms", new InitialContext()); jndiTemplate.bind("jms/Qualitas.EclipseLinkCacheConnectionFactory", eclipseLinkCacheConnectionFactory); jndiTemplate.bind("jms/Qualitas.EclipseLinkCacheTopic", eclipseLinkCacheTopic); } }
Это все.
Запуск образца
Когда я запустил Jetty и Apache Camel, в веб-консоли ActiveMQ я увидел двух пользователей, подключенных к Qualitas.EclipseLinkCacheTopic. И когда я загрузил пример процесса WS-BPEL в свое веб-приложение, я увидел состояние UPLOADED, но через несколько долей секунды я увидел состояние PROCESSING и через несколько секунд наконец увидел состояние INSTALLED. Все работало как шарм.
Если вы заинтересованы в полном исходном коде, Qualitas размещается как на googlecode: http://code.google.com/p/qualitas/source/browse/, так и на GitHub: https://github.com/lukasz-budnik/. QUALITAS, На данный момент он находится в основной ветке, но через неделю он станет частью релиза 0.0.5-SNAPSHOT и будет помечен как 0.0.5-SNAPSHOT. Этот тег, конечно, будет стабильным. Мастер ветки не всегда может быть стабильным. Прежде чем клонировать основную ветку, убедитесь, что Дженкинс из CouldBees сказал, что это безопасно: https://qualitas.ci.cloudbees.com/job/Qualitas/modules . Qualitas — это распределенная система, и для ее запуска необходимо настроить несколько вещей. Пожалуйста, обратитесь к http://code.google.com/p/qualitas/wiki/BuildingTheProject и http://code.google.com/p/qualitas/wiki/RunningTheProject вики-страницам.
Резюме
Любые комментарии приветствуются. Было бы неплохо иметь координацию кэша на основе AMQP в EclipseLink. Я думаю о добровольчестве для реализации этой функции ?