【问题标题】:ApacheMQ Artemis keep messages with no routeApacheMQ Artemis 保留没有路由的消息
【发布时间】:2019-01-17 02:17:18
【问题描述】:

我正在使用 Artemis 2.6.2 仅与 STOMP 和以下星座:

经纪人:

  • broker.xml 中没有配置队列,一切都是自动创建的。

服务器:

  • 订阅目的地TaskResponse,不带选择器/过滤器
  • 发送到目标TaskRequest,标头clientId = ID(服务器请求的客户端ID)

客户端 123:

  • 订阅目的地TaskRequest,选择器clientId = 123
  • 发送到目的地TaskResponse,标头clientId = 123

当我在Artemis Console 观看时,会发生以下情况:

  1. 没有连接服务器和客户端:不存在地址或队列

  2. 服务器连接:Artemis 创建一个多播地址 TaskResponse 和一个带有空过滤器的地址的多播队列

  3. 客户端 123 连接:Artemis 创建一个多播地址 TaskRequest 和该地址的多播队列,过滤器 clientId = 123

  4. 消息交换:消息按预期从服务器传输到客户端并返回到服务器。

  5. 客户端 123 断开连接:Artemis 删除多播地址 TaskRequest 和过滤器 clientId = 123 的对应多播队列

  6. 服务器向客户端 123 的 TaskRequest 发送消息:根据服务器上的STOMP 客户端消息发送成功。在代理上,消息消失了。

  7. 反之亦然:客户端 123 已连接而服务器未连接:根据客户端 123 上的 STOMP 客户端,消息发送成功。在代理上,消息消失了。

我的猜测是消息被丢弃是因为没有到订阅者的路由。如果我在 broker.xml 的地址设置部分启用“send-to-dla-on-no-route”选项,则消息直接进入死信队列。

您知道在订阅者重新连接之前保留消息的方法吗?

附录 1:STOMP 消息

我将Stomp.Net LibrarySelectorsCore Example 一起使用,但仅简化为选择器s1。工作流程与我上面写的有点不同。

不幸的是,我没有找到将 STOMP 消息记录到 Artemis 文件中的示例。因此我用WireShark记录了数据包,导出为文本并上传到Gist StompMessages.txt。您可以在那里看到不同的 STOMP 消息,例如搜索 CONNECT、SEND 等。

解决方案

解决方案是在broker.xmlacceptor 元素中使用选项anycastPrefix=/queue/ 来强制队列输入ANYCAST

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

【问题讨论】:

    标签: stomp activemq-artemis


    【解决方案1】:

    您观察到的是预期的行为。如果您将消息发送到没有队列的地址(或者用 STOMP 术语 - 没有订阅者的目的地),那么该消息将无处可去并且将被丢弃。这是正常的发布/订阅语义。

    如果您想在没有订阅者的情况下保留消息,您可以:

    1. 使用任播(即点对点)语义而不是多播。这在Artemis documentation 中进行了讨论。
    2. 使用Artemis documentation 中讨论的“持久”STOMP 订阅者。这里需要注意的是,仍然需要在发送消息之前创建订阅,并且您还需要确保在完成后删除订阅,否则它可能会累积消息。

    【讨论】:

    • 感谢您的快速答复。我将检查提到的两个选项...
    • 我已经检查了这两个命题。不幸的是,他们需要在 STOMP 客户端上进行两项调整。您是否知道仅通过更改代理配置来达到该行为的方法?我发现一些有趣的事情是我不能强制代理自动创建持久队列。在docs 它说:Queues which are auto-created are durable, non-temporary, and non-transient.
    • 我需要更多地了解客户正在做什么以提供任何额外的输入。您是否有一系列可以分享的 STOMP 框架来展示客户的行为?
    • 我已在附录 1 的原始问题中添加了详细信息。感谢您查看。
    • 我查看了StompConnection.java:session.createQueue(simpleQueue, simpleQueue, routingType == null ? addressSettings.getDefaultQueueRoutingType() : routingType, null, false, true, true); 我看到这个方法调用中的持久标志是 null 并且 java 可能使用 false 作为默认值。这与上述评论中引用的文档相矛盾。
    猜你喜欢
    • 1970-01-01
    • 2019-01-11
    • 1970-01-01
    • 2018-09-13
    • 2014-09-04
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多