Могут ли бины, управляемые сообщениями (MDB), прослушивать "внешний" MQ?
Я пытаюсь понять концепции, связанные с MDB, MQ, JMS. Я провел исследование SO, прежде чем задавать этот вопрос.
Это возможный сценарий:
MDB развернут на сервере приложений, скажем, на JBOSS (на физическом сервере A).
MQ (скажем, ApacheMQ) на разнице физического сервера-B.
Так может ли MDB, развернутый на физическом сервере-A, получать сообщения от физического сервера-B?
Если это возможно, то использует ли MDB JMS API?
Я слышал, что у Jboss есть MQ, который, как я полагаю, связан с сервером приложений Jboss; однако я хочу MDB на другом сервере и MQ на другом физическом сервере.
Ценю вашу помощь в понимании этого.
3 ответа
В этом есть 4 настоящие части.
1) Ваша заявка. MDB - это приложение, которое реализует J2EE Message Driven Bean API, что в его самой простой форме означает, что у него есть функция onMessage(), которая будет вызываться сервером приложений при поступлении сообщений.
2) Сервер приложений J2EE, JBOSS, является примером. Он получает сообщения от клиента MQ и передает их в MDB.
3) MQ клиент. Это код, написанный поставщиком MQ (IBM/Apache/etc), который реализует JCA RA и JMS-части J2EE. Приложения могут взаимодействовать с этим клиентом через JMS для размещения и получения сообщений, хотя, когда вы взаимодействуете как MDB, вы будете управляться с помощью метода onMessage(). Этот клиент передает сообщения на сервер приложений, который управляет приложениями.
4) MQ сервер. IBM MQ называет это "администратором очередей", и это может существовать где угодно. Клиент из #3 подключится к администратору очередей по сети.
# 1, # 2 и #3 должны быть на одной физической машине (и работать в той же JVM). № 4 может быть где угодно, так как доступ к нему осуществляется по сети.
Для решения ваших вопросов:
Так может ли MDB, развернутый на физическом сервере-A, получать сообщения от физического сервера-B?
да
Если это возможно, то использует ли MDB JMS API?
MDB управляется сервером приложений, использующим J2EE API, JMS является лишь частью этого.
Кстати, "MQ" - это название продукта, а не концепт. Общее название - "Поставщик сообщений". IBM MQ и ApacheMQ являются поставщиками сообщений.
Для людей, использующих Glassfish4/Payara-Server, это эквивалентно @Doug Grove
@ResourceAdapter
:
@MessageDriven(
name = "foo",
activationConfig = {
@ActivationConfigProperty(propertyName = "resourceAdapter", propertyValue = "activemq-rar-x-x-x"),
:
:
когда activemq-rar-xxx - это адаптер ресурсов ActiveMQ, развернутый в AS.
С уважением.
Пример MDB, который активируется удаленным экземпляром MQ:
/**
* WebSphereMQ.java
*
* Created on Sep 21, 2012, 9:11:29 AM
*
* To the extent possible under law, Red Hat, Inc. has dedicated all copyright to this
* software to the public domain worldwide, pursuant to the CC0 Public Domain Dedication. This
* software is distributed without any warranty.
*
* See <http://creativecommons.org/publicdomain/zero/1.0/>.
*
*/
package org.jboss.sample.mq;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.MessageDriven;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.jboss.ejb3.annotation.Pool;
import org.jboss.ejb3.annotation.ResourceAdapter;
import org.jboss.logging.Logger;
/**
*
*/
@MessageDriven(name = "WebSphereMQ", activationConfig = {
@ActivationConfigProperty(propertyName = "maxPoolDepth", propertyValue="100"),
@ActivationConfigProperty(propertyName = "maxMessages", propertyValue="1"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "hostName", propertyValue = "10.0.0.150"),
@ActivationConfigProperty(propertyName = "port", propertyValue = "1414"),
@ActivationConfigProperty(propertyName = "userName", propertyValue = "redhat"),
@ActivationConfigProperty(propertyName = "password", propertyValue = "redhat"),
@ActivationConfigProperty(propertyName = "channel", propertyValue = "SYSTEM.DEF.SVRCONN"),
@ActivationConfigProperty(propertyName = "queueManager", propertyValue = "REDHAT.QUEUE.MANAGER"),
@ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "true"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "jms/queue/gssQueue"),
@ActivationConfigProperty(propertyName = "transportType", propertyValue = "CLIENT") })
@Pool(value="MQpool")
@ResourceAdapter(value="wmq.jmsra.7.5.0.4.rar")
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class WebSphereMQ implements MessageListener {
private static final Logger logger = Logger.getLogger(WebSphereMQ.class);
/*
* (non-Javadoc)
*
* @see javax.jms.MessageListener#onMessage(javax.jms.Message)
*/
public void onMessage(Message message) {
try {
logger.info("Received message: " + message.getJMSMessageID() + " : " + ((TextMessage)message).getText());
try {
Thread.sleep(10000);
} catch(Exception e) {
logger.info("interrupted");
}
}
}