【问题标题】:In Wildfly, MDB listening to external ActiveMQ gets a null JMSMessageId在 Wildfly 中,侦听外部 ActiveMQ 的 MDB 得到一个空的 JMSMessageId
【发布时间】:2019-06-25 21:44:01
【问题描述】:

我正在测试 Wildfly16 / JBoss 7.2 与 ActiveMQ Artemis 2.7 的连接性。

我编写了一个简单的 MDB,它可以使用来自远程 ActiveMQ Artemis 服务器的消息。

我正确获取了有效负载(文本消息)和 CorrelationId,但收到的 MessageId 为空!这看起来很奇怪,而且很烦人,因为我想实现请求/回复。

  • 为了使 Wildfly 能够访问外部 ActiveMQ Artemis 服务器,我按照31.3. Configuring the Artemis Resource Adapter to Connect to Red Hat JBoss AMQ 7 中指示的步骤进行操作。它奏效了。
  • 我创建了一个简单的 Java 客户端,它能够直接发送/使用/浏览队列。当我使用这个客户端消费一条消息时,我会得到 MessageId、CorrelationId 和所有我期望的东西。
  • Wildfly 16、17 和 JBoss 7.2 上的消息驱动 Bean 出现此问题(我都尝试过)。
  • 我在 Wildfly 上部署的 MDB 的 Jar 没有依赖关系 (6Kb)

MDB的代码下面

import java.util.Properties;
import java.util.logging.Logger;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;

import javax.jms.*;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.jboss.ejb3.annotation.ResourceAdapter;

@ResourceAdapter("activemq-ra-remote")
@MessageDriven(name = "JmsTestMDB", activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "testReqQueue"),
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")})
public class WildflyMdb implements MessageListener {
  private static final Logger LOGGER = Logger.getLogger(WildflyMdb.class.toString());

  public void onMessage(Message rcvMessage) {
    TextMessage txtMessage = null;
    try {
      if (rcvMessage instanceof TextMessage) {
    txtMessage = (TextMessage) rcvMessage;
       LOGGER.info("Received Message from queue: MessageId=" + rcvMessage.getJMSMessageID() + 
                   ", CorrelationId=" + rcvMessage.getJMSCorrelationID() +
                   ", Text='" + txtMessage.getText() + "'");

       LOGGER.info("rcvMessage (toString): " + rcvMessage.toString());

    } catch (Exception e) {
       LOGGER.severe("EXCEPTION:" + e.getMessage());
    }
 }

当我使用 Java 客户端发送以下消息时:

  • 消息 ID:ID:DEVTEMP-PC-49242-1561392550500-1:1:1:1:1
  • CorrelationId:CID:20190624180910
  • 短信:“这是我的测试短信”

我从 Wildfly 中的 MDB 获得以下日志:

16:23:29,694 INFO  [class com.fluide.mdb.WildflyMdb] (Thread-360 (ActiveMQ-client-global-threads)) Received Message from queue: MessageId=null, CorrelationId=CID:20190624180910, Text='This is my test message'
16:23:29,695 INFO  [class com.fluide.mdb.WildflyMdb] (Thread-360 (ActiveMQ-client-global-threads)) rcvMessage (toString): ActiveMQMessage[null]:PERSISTENT/ClientMessageImpl[messageID=946860, durable=true, address=testReqQueue,userID=null,properties=TypedProperties[__AMQ_CID=ID:DEVTEMP-PC-49242-1561392550500-0:1,_AMQ_GROUP_SEQUENCE=0,__HDR_BROKER_IN_TIME=1561392550749,_AMQ_ROUTING_TYPE=1,__HDR_ARRIVAL=0,__HDR_REPLY_TO=[0000 0011 6401 000D 7465 7374 5265 7370 5175 6575 65),__HDR_COMMAND_ID=5,JMSCorrelationID=CID:20190624180910,__HDR_PRODUCER_ID=[0000 0039 7B01 0025 4944 3A44 4556 5445 4D50 2D50 432D 3439 3234 322D 3135  ... 31 3339 3235 3530 3530 302D 313A 3100 0000 0000 0000 0100 0000 0000 0000 01),__HDR_MESSAGE_ID=[0000 004C 6E00 017B 0100 2549 443A 4445 5654 454D 502D 5043 2D34 3932 3432  ...  0000 0000 0001 0000 0000 0000 0001 0000 0000 0000 0001 0000 0000 0000 0000),__HDR_DROPPABLE=false]]

如您所见,MessageId 返回为 null,这看起来不正确。 有什么想法吗?

【问题讨论】:

  • 我知道您观察到的行为不是预期的,但我不明白为什么您实际上首先需要消息 ID。我不知道任何需要消息 ID 的请求/回复模式。你能详细说明一下吗?
  • 另外,消息是如何发送的(例如,正在使用什么客户端库)?看起来您可能正在使用 OpenWire 客户端来发送消息。对吗?
  • 嗨贾斯汀,感谢您的回复!所以使用 JMSMessageID 背后的原因是它是 Oracle SOA JMS 连接器所使用的:它记录生成消息时返回的 JMSMessageID。在响应中,它读取 JMSCorrelationID 并将其与请求的 JMSMessageID 相关联。我们希望将我们的服务从 Weblogic/Oracle AQ 迁移到 Wildfly/ActiveMQ。
  • 我在我的 java 客户端中使用activemq-all-5.12.0.jar。初始上下文工厂是org.apache.activemq.jndi.ActiveMQInitialContextFactory,我正在查找ConnectionFactory
  • 我忘了:我也测试了JMSReplyTo,它也返回了null

标签: jboss jms wildfly activemq-artemis


【解决方案1】:

由于您使用来自activemq-all-5.12.0.jar 的 OpenWire 协议使用独立 Java 客户端发送消息,并使用 Artemis 核心协议在 Wildfly/EAP 上使用 MDB 接收消息,我相信您在 ActiveMQ 中使用this bug Artemis 导致使用不同协议发送和接收的消息的消息 ID 为空。已发送拉取请求,因此该问题应在 2.10.0 中修复。

如果您不想等待 2.10.0 发布,则可以通过使用独立 Java 应用程序中的 Artemis 核心 JMS 客户端实现来解决此问题。只需放入 Artemis 客户端 jar(来自 /lib/client 目录)并将初始上下文工厂更改为 org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory

【讨论】:

  • 谢谢贾斯汀。那么您的建议是调整 Artemis 服务器 的客户端 jar:apache-artemis-2.7.0/lib/client/artemis-jms-client-all-2.7.0.jar?那是对的吗?不管怎样,我试着给你一个反馈。
  • 我建议您在独立的 Java 应用程序中使用 ActiveMQ Artemis JMS 客户端,而不是您当前使用的 ActiveMQ 5.x JMS 客户端。无需在 Artemis 服务器上进行任何更改。
  • 是的,这就是我经过更多思考后的想法,我做到了。它改变了相当多的行为:我发送到testReqQueue,现在它到达了 Artemis 服务器上的jms.queue.testReqQueue(它添加了 jms.queue 前缀)。我正在调整 MDB,我给你一个反馈。
  • 是的!有用!非常感谢。就是这样!因此,正如您所建议的,我使用了取自 artemis 服务器的 <ARTEMIS_HOME>/lib/client directoryartemis-jms-client-all-2.7.0.jar,并替换了我在独立客户端中使用的 activemq-all-5.12.0.jar。我还在同一个独立客户端中将我的独立客户端从org.apache.activemq.jndi.ActiveMQInitialContextFactory 更改为org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory,现在每个人都说相同的语言! Wildfly 中的 MDB 获得了正确的信息。再次感谢贾斯汀!
【解决方案2】:

EAP 7.2 在 Artemis 2.x 上,因此您不必那样做。您可以在子系统级别使用简单配置良好的池连接工厂:http://wildscribe.github.io/WildFly/16.0/subsystem/messaging-activemq/pooled-connection-factory/index.html

【讨论】:

  • 感谢@ehsavoie 的回答。但我不明白你的意思。我认为通过遵循redhat doc,我遵循了正确的步骤(实际上是通过池连接工厂)。在得到这个迁移任务之前,我没有做任何 JMS。所以对我来说并不容易。如果您能提供更多指导,我将不胜感激!
  • docs.wildfly.org/17/… 是我所指的
猜你喜欢
  • 2023-03-17
  • 2013-11-07
  • 2015-09-20
  • 1970-01-01
  • 2019-05-18
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
相关资源
最近更新 更多