问题
I am trying to understand concepts related to MDB, MQ, JMS. I did research on SO before asking this question.
Is this possible scenario:
MDB deployed on Application Server, say on JBOSS (on physical Server-A).
MQ (say ApacheMQ) on a difference physical server-B.
So can the MDB deployed in physical server-A get messages from physical server-B?
If this is possible, then does MDB use JMS API's?
I have heard Jboss has MQ, which i presume MQ withing Jboss application server; however i want MDB in a different server and MQ server on a different physical server.
Appreciate your help in understanding this.
回答1:
There are 4 real parts to this.
1) Your application. An MDB is an application which implements the J2EE Message Driven Bean API, which in its simplest form means it has an onMessage() function which will be invoked by the application server when messages arrive.
2) The J2EE application server, JBOSS is an example. This receives messages from the MQ client, and forwards them to the MDB.
3) The MQ client. This is the code written by the MQ provider (IBM/Apache/etc) which implements the JCA RA and JMS parts of J2EE. Applications can interact with this client via JMS to put and get messages, though when you're interacting as an MDB you'll be driven via your onMessage() method. This client hands messages to the application server, which drives the applications.
4) The MQ server. IBM MQ calls this a 'queue manager', and this can exist anywhere. The client from #3 will connect to the queue manager over the network.
#1, #2, and #3 need to be on the same physical machine (and run in the same JVM). #4 can be anywhere as its accessed over the network.
To address your points:
So can the MDB deployed in physical server-A get messages from physical server-B?
Yes
If this is possible, then does MDB use JMS API's?
The MDB is driven by the application server using the J2EE API, JMS is just a part of this.
By the way, 'MQ' is the name of product rather than a concept. The generic name is 'Messaging Provider'. IBM MQ and ApacheMQ are both messaging providers.
回答2:
An example of an MDB that is activated by a remote MQ instance:
/**
* 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");
}
}
}
回答3:
For people are using Glassfish4/Payara-Server, this is the equivalent for @Doug Grove
@ResourceAdapter
:
@MessageDriven(
name = "foo",
activationConfig = {
@ActivationConfigProperty(propertyName = "resourceAdapter", propertyValue = "activemq-rar-x-x-x"),
:
:
when activemq-rar-x-x-x is the ActiveMQ resource adapter deployed at AS.
Regards.
来源:https://stackoverflow.com/questions/31192421/can-message-driven-beans-mdb-listen-on-external-mq