我的制作人看起来像这样:
$connection = new AMQPStreamConnection(
$settings['amqp']['host'],
$settings['amqp']['port'],
$settings['amqp']['username'],
$settings['amqp']['password']
);
$channel = $connection->channel();
$channel->queue_declare($settings['amqp']['queue'], false, true, false, false);
$msg = array();
$msg['time'] = time();
$msg = new AMQPMessage(json_encode($msg), array('delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT));
$channel->basic_publish($msg, '', $settings['amqp']['queue']);
$channel->close();
$connection->close();
我的消费者看起来像这样:
$connection = new AMQPStreamConnection(
$settings['amqp']['host'],
$settings['amqp']['port'],
$settings['amqp']['username'],
$settings['amqp']['password']
);
$channel = $connection->channel();
$channel->queue_declare($settings['amqp']['queue'], false, true, false, false);
$callback = function($message) {
//echo $message->body . "\n";
//echo $message->delivery_info['delivery_tag'] . "\n";
var_dump($message) . "\n";
$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
};
$channel->basic_qos(null, 30, null);
$channel->basic_consume($settings['amqp']['queue'], '', false, false, false, false, $callback);
try {
while(count($channel->callbacks)) {
$channel->wait();
}
} catch (Exception $e){
die();
}
由于我已将 basic_qos 设置为 null,30,null 我的消费者从群集中检索30封邮件的块。
我的目标是将这30个作为一个群体来识别。接下来的30人是不同的群体。
类似的东西:
注意:示例PHP + BASH !!!
$callback = function($message) {
mkdir -p /tmp/$message->delivery_info['prefetch_group']
echo $message->body > /tmp/$message->delivery_info['prefetch_group']/$message->delivery_info['delivery_tag']
};
最后。我将为每个块提供一个带有消息内容的目录。
当然 $ message-> delivery_info [' prefetch_group'] 不存在。而我在 $ message
中找不到任何有用的东西只有在完成所有流程后,才能理想地为每个块发送basis_ack(30条消息)。
有什么想法来解决这个问题吗?
答案 0 :(得分:0)
在收到另外30条消息之前,没有什么可以阻止您处理30条消息。
multiple
标记设置为" true&#34 ;;这将确认收到第30条消息之前收到的所有消息作为一个警告,如果消息处理器失败/崩溃与第30条消息,并且你不承认其他29消息,那么你最终将把那些重新交付给你,所以这可能是你设计中要考虑的事情。
另请注意from the spec:
服务器可以提前发送的数据少于客户端指定的预取窗口所允许的数据,但它不能发送更多数据。
答案 1 :(得分:0)
经过一些研究后,我做到了这一点。
使用 basic_get 代替 basic_consume :
CODE NOT PROBED !!!想做个例子。
16 $connection = new AMQPStreamConnection(
17 $settings['amqp']['host'],
18 $settings['amqp']['port'],
19 $settings['amqp']['username'],
20 $settings['amqp']['password']
21 );
22
23 $channel = $connection->channel();
24 $channel->queue_declare($settings['amqp']['queue'], false, true, false, false);
25
26 $messages = Array();
27 for ($i=0; $i < 30; $i++) {
28 $messages[] = $channel->basic_get($settings['amqp']['queue']);
29 }
30
31 $now = time();
32 foreach($messages as $message) {
33 // DO WHATEVER YOU WANT WITH EACH MSG
34 // system('mkdir -p /tmp/' . $now);
// system('echo ' . $message->body . '> /tmp/' . $now . '/' . $message->delivery_info['delivery_tag']);
35 echo $message->body . "\n";
36 }
37
38 // system('tar /tmp/' . $now . '.gz cvfz /tmp/' . $now);
39
40 foreach($messages as $message) {
41 $channel->basic_ack($message->delivery_info['delivery_tag']);
42 }
43
44 $channel->close();
45 $connection->close();
这只是一个POC。有必要:
我需要详细了解 basic_get vs basic_consume ,但这个解决方案对我来说似乎不错。