我需要使用PHP在ActiveMQ队列中找到特定的消息并将其删除。
AFAIK这样做的唯一方法是读取当前排队的所有消息并确认我感兴趣的一条消息。(The example in the PHP manual for Stomp::ack或多或少做同样的事情,它们不会全部读取消息,但只确认匹配的消息。)
所以,我写了这段代码(显然这只是相关部分):
class StompController {
private $con;
public function __construct($stompSettings) {
try {
$this->con = new Stomp($stompSettings['scheme']."://".$stompSettings['host'].":".$stompSettings['port']);
$this->con->connect();
$this->con->setReadTimeout(5);
} catch(StompException $e) {
die('Connection failed:' .$e->getMessage());
}
}
public function __destruct() {
$this->con->disconnect();
}
public function ackMessageAsRead($recipient,$message) {
if($this->con->isConnected()) {
//Subscribe to the recipient user's message queue.
$this->con->subscribe("/queue/".$recipient);
//Read all messages currently in the queue (but only ACK the one we're interested in).
while($this->con->hasFrameToRead()) {
$msg = $this->con->readFrame();
if($msg != null && $msg != false) {
//This is the message we are currently reading, ACK it to AMQ and be done with it.
if($msg->body == $message) {
$this->con->ack($msg);
}
}
}
} else {
return false;
}
}
}
根据我的逻辑,这应该有效。 尽管运行代码,但正在读取一个随机 消息,尽管检查了更多帧。
下一帧似乎只是在我们当前正在读取的帧已经确认时才准备好。 (当我手动确认所有消息时,while
循环按预期工作,所有消息都被处理。
有没有人知道如何从队列中获取完整的消息集,而不是确认所有消息?我可以确认所有这些并将之后我不感兴趣的那些放回队列中,但这种已经低效的查找单个消息的方式在这种情况下会变得非常低效。
答案 0 :(得分:1)
我认为这是一个问题,因为将activemq.prefetchSize
设置为1. ActiveMQ使用预取大小来确定可以在任何时间点向消费者分派的消息数量。一旦达到预取大小,在消费者开始发回确认之前,不再向消费者分派消息。增加预取大小应该以我的最佳知识来解决您的问题。
有关预取限制的详细信息,请阅读http://activemq.apache.org/what-is-the-prefetch-limit-for.html。