Системная интеграция — хороший вызов. Особенно, когда вы ищете стандарты связи и надежные решения. В современном мире микросервисов все говорят о сервисах 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» . |