【问题标题】:Artemis STOMP messages not delivered to OPENWIRE JMS clientsArtemis STOMP 消息未传递到 OPENWIRE JMS 客户端
【发布时间】:2021-06-04 23:00:50
【问题描述】:

我们正在尝试从 ActiveMQ 5.x 升级到最新的 Artemis (2.17),但我们的一个应用程序让我们感到悲痛。

该应用程序是使用 STOMP 的较旧的 PHP Web 应用程序。它创建一个临时响应队列,向目标发送消息,然后等待响应。在 ActiveMQ 5.x 下,这可以正常工作(并且已经使用了多年),但在 Artemis 中,请求只会挂起直到超时。

目标是基于 JMS API 和 Openwire 的 Java 应用程序。我们的大多数应用程序都是这样,相互通信没有问题……只有这一个 PHP web 应用程序有问题,而且它似乎是我们唯一基于 STOMP 的东西。

我们单独运行单个事务并启用 Artemis STOMP 调试,这是我们看到的:

07:47:42,180 STOMP(/10.0.0.5:40618, f985f04d): IN << StompFrame[command=CONNECT, headers={login=<appid>, passcode=<app-password>}]
07:47:42,196 STOMP(/10.0.0.5:40618, f985f04d):OUT >> StompFrame[command=CONNECTED, headers={session=f985f04d}]
07:47:42,203 STOMP(/10.0.0.5:40618, f985f04d): IN << StompFrame[command=SUBSCRIBE, headers={ack=client, destination=/temp-queue/Reply-604379ee2f900, activemq.prefetchSize=1}]
07:47:42,235 STOMP(/10.0.0.5:40618, f985f04d): IN << StompFrame[command=SEND, headers={expires=1615035162000, destination=/queue/target, content-type=text/plain, reply-to=/temp-queue/Reply-604379ee2f900}, body=<--- message text---> body-bytes=[<--- message bytes --->, size=0]
07:48:42,247 STOMP(/10.0.0.5:40618, f985f04d): IN << StompFrame[command=DISCONNECT, headers={}]

问题的核心似乎是来自上面显示的“SEND”操作的消息永远不会到达接收者。我们已验证接收器在线,并且它响应其他使用 JMS 和 Openwire 连接进行连接的客户端 - 但此 STOMP 消息未路由到目的地。

如果我们关闭 Artemis 并恢复到 ActiveMQ 5.x,应用程序可以正常工作。

我们使用的是默认配置:

<acceptors>

         <!-- useEpoll means: it will use Netty epoll if you are on a system (Linux) that supports it -->
         <!-- amqpCredits: The number of credits sent to AMQP producers -->
         <!-- amqpLowCredits: The server will send the # credits specified at amqpCredits at this low mark -->
         <!-- amqpDuplicateDetection: If you are not using duplicate detection, set this to false
                                      as duplicate detection requires applicationProperties to be parsed on the server. -->
         <!-- amqpMinLargeMessageSize: Determines how many bytes are considered large, so we start using files to hold their data.
                                       default: 102400, -1 would mean to disable large mesasge control -->

         <!-- Note: If an acceptor needs to be compatible with HornetQ and/or Artemis 1.x clients add
                    "anycastPrefix=jms.queue.;multicastPrefix=jms.topic." to the acceptor url.
                    See https://issues.apache.org/jira/browse/ARTEMIS-1644 for more information. -->


         <!-- Acceptor for every supported protocol -->
         <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true</acceptor>

         <!-- AMQP Acceptor.  Listens on default AMQP port for AMQP traffic.-->
         <acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpMinLargeMessageSize=102400;amqpDuplicateDetection=true</acceptor>

         <!-- STOMP Acceptor. -->
         <acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>

         <!-- HornetQ Compatibility Acceptor.  Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
         <acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>

         <!-- MQTT Acceptor -->
         <acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor>

      </acceptors>

我们需要一些神奇的配置来将这些 STOMP 消息路由到正确的目的地吗?

【问题讨论】:

  • 编辑了我的问题以包括我们的接受器配置。
  • @Justin:我很欣赏这次更新,但由于内部安排,我们无法再测试一两个月内的问题应用程序。当我们有机会再次测试时,我肯定会发布另一个更新,当然如果您创建的错误报告得到解决,我们也会尝试更新。

标签: jms stomp activemq-artemis


【解决方案1】:

第一个问题是消息发送到的destination。如the ActiveMQ 5.x STOMP documentation 中所述,SEND 帧的 destination 标头上使用的 /queue/ 前缀会自动剥离。但是,在 ActiveMQ Artemis 中,这需要通过ActiveMQ Artemis STOMP documentation 中讨论的anycastPrefix 参数显式配置,例如:

<acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true;anycastPrefix=/queue/;multicastPrefix=/topic/</acceptor>

为了完整性,这里也配置了multicastPrefix

配置完成后,您的消息将按预期发送至target

但是,我认为SUBSCRIBE 帧的destination 标头上使用的/temp-queue/ 前缀以及SEND 帧上的reply-to 标头仍然存在问题。 ActiveMQ 5.x 也特别对待这些(虽然我找不到关于它的文档)。 ActiveMQ Artemis 不会为这些创建临时资源,但我认为您仍然可以获得所需的行为,因为代理可以自动创建和自动删除资源,就像它们是临时的一样。您需要在此处配置的主要内容是像以前一样的前缀,例如:

<acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true;anycastPrefix=/queue/,/temp-queue/;multicastPrefix=/topic/,/temp-topic/</acceptor>

由于您的 Stomp 客户端使用 /temp-queue/ 指定 reply-to 标头,而您的 OpenWire 客户端正在使用此标头,因此您还需要更改您的 OpenWire acceptor,例如:

<acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true;anycastPrefix=/temp-queue/;multicastPrefix=/temp-topic/</acceptor>

我已经打开了ARTEMIS-3164 来实现一个前缀来识别 ActiveMQ Artemis 中的临时资源。

【讨论】:

  • 我们有机会在一夜之间测试了推荐的更改,但很抱歉,结果喜忧参半。好消息是,通过您发布的更新配置,消息确实可以从 STOMP 应用程序正确地传送到 OPENWIRE 应用程序。然而,响应并没有通过其临时队列返回给 STOMP 客户端。在控制台中,我们可以看到响应队列(以“/temp-queue”为前缀),如果我浏览这些队列,它们似乎有正确的数据——除了当 STOMP 应用程序订阅时没有为这些队列创建消费者它的回应。
  • ...我们测试的另一件事是 STOMP 活动的痕迹与我之前发布的完全相同...
  • ...另一个小提示:处理这些消息的 OPENWIRE 消费者调用“getJMSReplyTo()”来获取回复队列名称。当它向这个 ReplyTo 地址发送消息时,它会收到“DestinationDoesNotExistException”。同样的流程在 ActiveMQ 5.x 中运行良好,并且在客户端使用 OPENWIRE 时也适用于 Artemis。这似乎有点奇怪,因为我可以在控制台中看到待处理的响应消息,尽管它们没有消费者。
  • 我更新了我的答案以解决您的 cmets。目前我不确定DestinationDoesNotExistException。您是否启用了地址和队列自动创建功能?
猜你喜欢
  • 2020-10-04
  • 2015-07-05
  • 1970-01-01
  • 2013-09-12
  • 2013-02-21
  • 2010-11-05
  • 1970-01-01
  • 2019-08-18
相关资源
最近更新 更多