【问题标题】:JMS queue and message driven bean work strangely in websphere 8.5JMS 队列和消息驱动 bean 在 websphere 8.5 中工作异常
【发布时间】:2015-09-27 11:35:06
【问题描述】:

我的项目是基于 websphere 8.5 构建的,我们决定在我的项目中使用 JMS quque 作为消息。

所以,我创建了一个名为 MyBus 的总线,还创建了一个目的地 myBusDistination。

然后我创建了一个名为 myConF 的连接工厂

然后我创建了两个 JMS 队列,一个是带有 JNDI jndi/myQueue1 的 myQueue1。另一个是带有 JNDI jndi/mQueue2 的 myQueue2。

然后我创建了两个Activation规范,一个是myAS1 with JNDI jndi/myAS1,另一个是myAS2 with JNDI jndi/myAS2。

然后我创建了两个消息驱动的 bean,它们位于 EJB3.0 中,名为 MyMDB1 和 MyMDB2。 类代码是这样的,

@MessageDriven(mappedName = "jndi/myQueue1", activationConfig = {     @ActivationConfigProperty(propertyName = "destinationType", propertyValue     = "javax.jms.Queue") })
public class MyMDB1 implements MessageListener {
    @Override
    public void onMessage(Message message) {
    }
}

ejb_jar.xml是这样的,

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http:/java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee      http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
version="3.0" metadata-complete="false">
<display-name>My MDB</display-name>
<enterprise-beans>

    <message-driven>
        <display-name>MyMDB1</display-name>
        <ejb-name>MyMDB1</ejb-name>
        <ejb-class>com.test.mdb.MyMDB1</ejb-class>
        <message-destination-ref>
            <message-destination-ref-name>jndi/myQueue1</message-destination-ref-name>
            <message-destination-type>javax.jms.Queue</message-destination-type>
            <message-destination-usage>Consumes</message-destination-usage>
            <message-destination-link>jndi/myQueue1</message-destination-link>
        </message-destination-ref>
    </message-driven>

    <message-driven>
        <display-name>MyMDB2</display-name>
        <ejb-name>MyMDB2</ejb-name>
        <ejb-class>com.test.mdb.MyMDB2</ejb-class>
        <message-destination-ref>
            <message-destination-ref-name>jndi/myQueue2</message-destination-ref-name>
            <message-destination-type>javax.jms.Queue</message-destination-type>
            <message-destination-usage>Consumes</message-destination-usage>
            <message-destination-link>jndi/myQueue2</message-destination-link>
        </message-destination-ref>
    </message-driven>
</enterprise-beans>

而ibm-ejb-jar-bnd.xml是这样的,

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd"
version="1.0">

<message-driven name="MyMDB1">
    <jca-adapter activation-spec-binding-name="jndi/myAS1" destination-binding-name="jndi/myQueue1"/>
    <message-destination-ref name="jndi/myQueue1" binding-name="jndi/myQueue1" />
</message-driven>

<message-driven name="MyMDB2">
    <jca-adapter activation-spec-binding-name="jndi/myAS2" destination-binding-name="jndi/myQueue2"/>
    <message-destination-ref name="jndi/myQueue2" binding-name="jndi/myQueue2" />
</message-driven>

最后,这是我的测试代码,

Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
      "com.ibm.websphere.naming.WsnInitialContextFactory");
props.put(Context.PROVIDER_URL, "corbaloc:iiop:localhost:2809");               InitialContext ctx = new InitialContext(props);
ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jndi/myConF"); 
        Destination destination = (Destination) ctx.lookup("jndi/myQueue1");  
        Connection conn = factory.createConnection(); 
        Session session = conn.createSession(false, QueueSession.AUTO_ACKNOWLEDGE); 
        MessageProducer producer = session.createProducer(destination);

                    ObjectMessage objMsg = session.createObjectMessage();
        objMsg.setObject("MDB Test");

        producer.send(objMsg); 
        session.close();
        conn.close();

奇怪的是,

消息可以发送出去,消息可以被MDB MyMDB1处理(如果我在MyMDB1.onMesssage()中记录了一些东西)。但是,如果我再次发送消息。该消息将由 MyMDB2 处理。

有人对这个“奇怪的东西”有什么想法吗?

【问题讨论】:

    标签: queue jms websphere message-driven-bean


    【解决方案1】:

    据我了解,您创建了两个连接到同一目的地的 JMS 队列(jndi/myQueue1、jndi/myQueue2)。这就是为什么两个 MDB 都在等待来自该目的地的消息。结果,哪个从队列中获取消息的速度更快将运行。这是一个不好的做法。 在您的测试中,您只使用 jndi/myQueue1 和 jndi/myAS1 将消息放入目的地,但这并不意味着。 您可以尝试停止其中一个 MDB,然后您可以看到它只能在另一个 MDB 中运行,并且消息不会留在队列中。

    更新。如果需要两个不同的队列来接收不同的消息。你应该做这样的事情:

    1. 创建第二个目标,例如myDestination2
    2. 更改myQueue2(资源->JMS->队列)的配置。在连接块中,将“队列名称”从 myBusDistination 更改为 myDestination2
    3. 要为第二个 MDB 使用放置消息:

      ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jndi/myConF"); Destination destination = (Destination) ctx.lookup("jndi/myQueue2");

      将消息放到第一个没有任何变化:

      ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jndi/myConF"); Destination destination = (Destination) ctx.lookup("jndi/myQueue1");

    【讨论】:

    • 是的,你可能是对的,你知道让两个队列同时工作吗?因为我需要创建 2 个队列来接收消息
    • 如果您有 WebSphere MQ,您可以将消息放入主题并订阅 2 个不同的队列。在您的情况下,您可以制作一个 MDB,它将运行到具有业务逻辑的不同 bean。或者,如果有可能,您可以在您的公共汽车上创建 2 个不同的目的地并将消息放入两者。
    • 嗨 IRomanov,我需要 JMS quque,我需要创建队列来接收不同的消息,我无法理解的是,我已经把 myQueue1 用于 JNDI 查找,为什么消息也被处理通过 MyMDB2?是因为它们被指定为相同的队列名称吗?我的目的地1?如果我为 myQueue2 创建另一个目的地 myDestination2,我应该为 JNDI 查找做什么?我的意思是,如果我想向 myQueue1 发送消息,并希望让 MyMDB1 处理消息,我应该将 myQueue1 用于 JNDI 查找或将 myDestination1 用于 JNDI 查找?
    • 我已经更新了答案。您应该使用jndi/myQueue1jndi/myQueue2 进行JNDI 查找。是你想要的吗?
    【解决方案2】:

    您必须为每个队列创建一个总线目的地,因此在您的情况下,myBusDistination1 用于 queue1myBusDistination2 用于 queue2。然后,当您将发送到 queue1 时,MDB1 将收到消息,如果您将发送到 queue2,MDB2 将收到消息。如果您希望所有 MDB 收到相同的消息,则必须创建 topic 而不是队列,以及指向该主题的激活规范。

    您没有在问题中具体说明您要达到的目标。

    【讨论】:

    • 嗨,Gas,你是对的,我只创建了一个 Bus 和一个 Destination,正如你所知,在创建 JMS 队列时,我们必须指定队列名称,我将 myBusDistination1 放在 myQueue1 和 myQueue2 ,但是当我发送消息时,我已经给了 myQueue1 用于 JNDI 查找,我真的需要两个不同的队列,因为我需要接收不同的消息。我的问题是,当我想发送消息时,对于 JNDI 查找,我应该将值放在那里?我的意思是 myQueue1 还是 myDestination1?
    • @zhianABCD 您需要在巴士上创建 2 个不同的目的地。为什么要将相同的目的地放在不同的队列中?
    猜你喜欢
    • 2013-04-26
    • 2012-02-27
    • 2016-03-31
    • 2012-10-08
    • 1970-01-01
    • 2011-01-28
    • 2016-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多