如何在使用Stomp和ActiveMQ(以及Perl)时使用事务?

10

我正在尝试使用ActiveMQ替换一些定制的消息队列,并且需要使用Perl从中频繁地发送和接收消息。ActiveMQ提供了一个Stomp接口,而Perl则有Net::Stomp,看起来这应该是可行的,但实际上不是这样。

即使我发送一个BEGIN帧到Stomp,使用SEND发送的消息也会立即发布,如果我调用ABORT撤销事务,则什么也不会发生。

我找不到任何明确的答案表明它是否可能、是否不可能或是否存在相关配置。此外,Stomp似乎不是检查服务器错误响应的好协议。

我该怎么办?

3个回答

3

顺便提一下,询问Perl/ActiveMQ/Stomp问题的最佳场所是ActiveMQ用户论坛,因为许多Perl-Stomp爱好者都在那里闲逛。

处理STOMP事务的关键是确保您发送的每条消息或做出的每个确认都包括事务ID头。请参阅STOMP协议的事务处理部分

原因是,如果您的客户端是多线程的,使用STOMP可能会同时进行许多事务以及一些非事务性操作。


是的,我正在遵循Stomp协议规则并发送事务头。(我希望我能在这台机器上让tcpflow工作;tcpdump对于观察stomp来说太糟糕了。) 我也会尝试那个论坛,谢谢! - rjbs

1

请查看Net::Stomp::Receipt。它是Net::Stomp的子类,实现了从Stomp协议中的“返回收据”,并允许您确保正确接收您的消息,否则中止事务。


1

您必须将确认包装在事务中。

伪代码(或伪STOMP)如下:

  • BEGIN [TRANSACTION-ID] -> 发送到服务器
  • MESSAGE [MESSAGE-ID] (received) <- 从服务器接收
  • ACK [MESSAGE-ID] [TRANSACTION-ID] -> 发送到服务器
  • COMMIT [TRANSACTION-ID] -> 发送到服务器

我已经使用PHP驱动程序使其工作正常(修补了中止调用,以便在传递帧对象以确认时使用事务ID)。

不幸的是,在重新传递四条消息后,客户端停止。至少这是我的情况。


如果我有一个 while 循环,那么伪代码是在循环内还是 BEGIN 和 ABORT 在循环外? - obsessiveCookie
1
由于您需要为每个发送和接收的消息打开一个事务,所以它们会在循环内部。 - Phillip Whelan
交易ID每次都会设置为不同的值吗? - obsessiveCookie
使用COMMIT而不是ABORT会改变一切。它不会标记错误并重新排队消息,而是会将其删除。 - Phillip Whelan
1
交易标识符必须包含在内,对于每个打开的交易必须是唯一的,并且必须由客户端或消费者生成。 - Phillip Whelan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接