ApacheMQ Artemis保持消息无路由

时间:2018-08-09 14:45:25

标签: stomp activemq-artemis

我仅将Artemis 2.6.2用于STOMP和以下星座:

经纪人:

  • 没有在broker.xml中配置队列,所有内容都是自动创建的。

服务器:

  • 在没有选择器/过滤器的情况下订阅到目的地TaskResponse
  • 发送到标头clientId = ID(服务器将请求的客户端ID)的目的地TaskRequest

客户端123:

  • 使用选择器clientId = 123预订到目的地TaskRequest
  • 发送到标头clientId = 123的目标TaskResponse

当我看着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的地址设置部分中启用了“不路由发送到dla”选项,则消息将直接进入死信队列。

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

附录1:STOMP消息

我将Stomp.Net LibrarySelectorsCore Example一起使用,但仅减少到选择器s1。工作流程与我上面写的略有不同。

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

解决方案

解决方案是在anycastPrefix=/queue/的{​​{1}}元素中使用选项acceptor强制队列键入broker.xml

ANYCAST

1 个答案:

答案 0 :(得分:0)

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

如果即使没有订阅者也要保留消息,则可以:

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