Могут ли бины, управляемые сообщениями (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");
            }               
    }
}
Другие вопросы по тегам