Системная интеграция — хороший вызов. Особенно, когда вы ищете стандарты связи и надежные решения. В современном мире микросервисов все говорят о сервисах REST и протоколах на основе http. На самом деле этого никогда не будет достаточно для большинства корпоративных проектов, которые обычно имеют гораздо более сложный набор требований. Разумное решение — интеграция на основе службы сообщений Java. И хотя мы больше не рассматриваем централизованные инфраструктуры и ESB, мы хотим использовать интеграцию определенных сервисов по принципу «точка-точка». Давайте посмотрим, сможем ли мы заставить это работать и отправлять сообщения между JBoss WildFly и Oracle WebLogic Server.
Бизнес-кейс — от Java EE к микросервисам
Но сначала я хочу сделать шаг назад: зачем кому-то? Я думаю, что одной из основных причин такого сценария является медленный путь миграции. Отходя от монолитных одноплатформенных приложений, мы хотим быть достаточно гибкими, чтобы выделять отдельные сервисы из этих гигантских установок и делать их доступными в качестве сервиса. Предполагая, что это даже возможно, и унаследованное приложение имеет достойный дизайн. Или мы хотим продвигать отдельные услуги, скажем, с технической точки зрения. В этом конкретном примере мы не можем дождаться, чтобы включить функции Java EE 7 в наше приложение, и WebLogic по-прежнему в основном зависает на EE 6. Мы можем сделать это с помощью служб REST или даже WebServices, но нам может потребоваться больше. И именно здесь вступает в силу спецификация JMS .
Клиентские библиотеки Oracle JMS в WildFly
Чтобы отправлять сообщения между двумя разными серверами, вам нужно интегрировать отдельные клиентские библиотеки в отправляющую сторону. Для WebLogic это тонкий клиент WebLogic JMS (wljmsclient.jar). обеспечивает функциональность Java EE и WebLogic JMS, используя гораздо меньшую площадь клиента, чем установка WebLogic или полный клиент, и несколько меньшую площадь клиента, чем клиент Thin T3. На самом деле, он содержит API-интерфейсы JMS Java EE и реализации, которые будут напрямую конфликтовать с теми, которые предоставляет WildFly. Чтобы использовать их, нам нужно будет упаковать их в виде модуля и настроить JMS Bridge в HornetQ, чтобы использовать именно это. Первое, что нужно добавить новый модуль. Измените папку на wildfly-8.2.0.Final \ modules \ system \ layer \ base и создайте новую структуру папок: custom \ oracle \ weblogic \ main под ней. Скопируйте wlthint3client.jar из папки% MW_HOME% \ server \ lib здесь. Теперь вам нужно добавить файл дескриптора модуля module.xml:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
<module xmlns="urn:jboss:module:2.0" name="custom.oracle.weblogic"> <resources> <resource-root path="wlthint3client.jar"> <filter> <exclude-set> <path name="javax.ejb"/> <path name="javax.ejb.spi"/> <path name="javax.transaction"/> <path name="javax.jms"/> <path name="javax.xml"/> <path name="javax.xml.stream"/> </exclude-set> </filter> </resource-root> </resources> <dependencies> <module name="javax.api"/> <module name="sun.jdk" export="false" services="import"> <exports> <include-set> <path name="sun/security/acl"/> <path name="META-INF/services"/> </include-set> </exports> </module> <module name="com.sun.xml.bind" /> <module name="org.omg.api"/> <module name="javax.ejb.api" export="false" /> <module name="javax.transaction.api" export="false" /> <module name="javax.jms.api" export="false" /> <module name="javax.xml.stream.api" export="false" /> <module name="org.picketbox" optional="true"/> <module name="javax.servlet.api" optional="true"/> <module name="org.jboss.logging" optional="true"/> <module name="org.jboss.as.web" optional="true"/> <module name="org.jboss.as.ejb3" optional="true"/> <module name="org.hornetq" /> </dependencies></module> |
Этот файл определяет все необходимые ресурсы и зависимости вместе с соответствующими исключениями. Если это сделано, нам, наконец, нужен мост сообщений.
Мост сообщений HMS HornetQ
Функция моста JMS состоит в том, чтобы получать сообщения из исходного места назначения JMS и отправлять их в целевое место назначения JMS. Обычно источник или целевое назначение находятся на разных серверах. Мост также можно использовать для объединения сообщений с других серверов JMS, отличных от HornetQ, если они соответствуют JMS 1.1. Откройте standalone-full.xml и добавьте следующую конфигурацию в подсистему обмена сообщениями:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<jms-bridge name="wls-bridge" module="custom.oracle.weblogic"> <source> <connection-factory name="java:/ConnectionFactory"/> <destination name="java:/jms/sourceQ"/> </source> <target> <connection-factory name="jms/WFMessagesCF"/> <destination name="jms/WFMessages"/> <context> <property key="java.naming.factory.initial" value="weblogic.jndi.WLInitialContextFactory"/> <property key="java.naming.provider.url" value="t3://127.0.0.1:7001"/> </context> </target> <quality-of-service>AT_MOST_ONCE</quality-of-service> <failure-retry-interval>2000</failure-retry-interval> <max-retries>10</max-retries> <max-batch-size>500</max-batch-size> <max-batch-time>500</max-batch-time> <add-messageID-in-header>true</add-messageID-in-header> </jms-bridge> |
Как видите, он напрямую ссылается на модуль и имеет определение источника и цели. Источником является локальная очередь сообщений WildFly, которая определена в подсистеме обмена сообщениями:
|
1
2
3
|
<jms-queue name="sourceQ"> <entry name="java:/jms/sourceQ"/> </jms-queue> |
И целью является удаленная очередь плюс фабрика соединений, которые определены в WebLogic Server. Я предполагаю, что вы знаете, как это сделать, если нет, пожалуйста, обратитесь к этой документации . Вот и все. Теперь нам нужно отправить сообщение в нашу локальную очередь, и оно будет отправлено через мост через очередь WebLogic.
Тестирование моста — с верблюдом
Разверните bean-компонент, управляемый сообщениями, в WebLogic (да, вам придется упаковать его как ejb jar в ухо и все это). Этот конкретный пример просто выводит текст сообщения в регистратор.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
@MessageDriven(mappedName = "jms/WFMessages", activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")})public class LogMessageBean implements MessageListener { private final static Logger LOGGER = Logger.getLogger(LogMessageBean.class.getName()); public LogMessageBean() { } @Override public void onMessage(Message message) { TextMessage text = (TextMessage) message; try { LOGGER.log(Level.INFO, text.getText()); } catch (JMSException jmxe) { LOGGER.log(Level.SEVERE, jmxe.getMessage()); } }} |
Теперь нам нужен продюсер на сервере WildFly. Сделайте это, я на самом деле использую интеграцию WildFly-Camel JMS .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@Startup@ApplicationScoped@ContextName("jms-camel-context")public class JMSRouteBuilder extends RouteBuilder { @Override public void configure() throws Exception { // Initial Context Lookup Context ic = new InitialContext(); ConnectionFactory cf = (ConnectionFactory) ic.lookup("/ConnectionFactory"); // Create the JMS Component JmsComponent component = new JmsComponent(); component.setConnectionFactory(cf); getContext().addComponent("jms", component); // Build A JSON Greeting JsonObject text = Json.createObjectBuilder() .add("Greeting", "From WildFly 8").build(); // Send a Message from timer to Queue from("timer://sendJMSMessage?fixedRate=true.=10000") .transform(constant(text.toString())) .to("jms:queue:sourceQ") .log("JMS Message sent"); }} |
Вот и вся магия. Таймер отправляет текстовое сообщение JSON в локальную очередь, которая соединяется с WebLogic.
Еще несколько советов
Если вы хотите протестировать очередь WebLogic без моста, вам нужно будет включить wljmsclient в ваш проект. Поскольку это недоступно в репозитории Maven (AFAIK), вы можете просто установить его локально:
|
1
|
mvn install:install-file -Dfile=%MW_HOME%/wlserver/server/lib/wlthint3client.jar -DgeneratePom=true -DgroupId=custom.com.oracle -DartifactId=wlthint3client -Dversion=12.1.3 -Dpackaging=jar |
Другая важная вещь заключается в том, что вы столкнетесь с проблемами загрузки классов в WildFly, если попытаетесь использовать пользовательский модуль в любой другой области, кроме моста. Итак, обратите пристальное внимание, чтобы вы не использовали его где-то еще.
Мост имеет сравнительно большой интервал повторения отказов и настроен максимум попыток. Это обходной путь. Если WildFly запускается слишком быстро и мост пытается получить доступ к локальному sourceQ до того, как очередь будет настроена, это приведет к исключению.
- Найти полный исходный код в моей учетной записи GitHub .
| Ссылка: | Отправка сообщений JMS из WildFly 8 в WebLogic 12 с Camel от нашего партнера по JCG Маркуса Эйзела (Markus Eisele) из блога « Разработка программного обеспечения для предприятий с использованием Java» . |

