我试图理解为什么在使用amqp.node(https://github.com/squaremo/amqp.node)时,似乎我在出列或处理这些消息之前将所有消息排队。我希望发送和接收是交错的。
发送 - 接收 - 发送 - 接收
但是我得到了
发送-发送 - 接收 - 接收
在检查我的进程时,我发现在进入任何接收之前,我将首先完成所有发送。我已经写了一个简单的演示,说明我遇到的问题
var amqp = require('amqplib');
var prettyHrtime = require('pretty-hrtime');
var when = require('when');
var firstMesssage = false;
var time, diff, totaltime;
var received = 0;
amqp.connect('amqp://localhost', { noDelay: false } ).then(function(conn) {
process.once('SIGINT', function() { conn.close(); });
return conn.createChannel().then(function(ch) {
var ok = ch.assertQueue('hello', {durable: false});
ok = ok.then(function(_qok) {
return ch.consume('hello', function(msg) {
if(!firstMesssage){
time = process.hrtime();
firstMesssage = true;
}
received++;
console.log(new Date().getTime());
console.log(" [x] Received '%s' %s", msg.content.toString(), received);
if(received >= 10000){
diff = process.hrtime(time);
var words = prettyHrtime(diff);
console.log(words);
}
}, {noAck: true});
});
return ok.then(function(_consumeOk) {
console.log(' [*] Waiting for messages. To exit press CTRL+C');
});
});
}).then(null, console.warn);
var numberToSend = 10000;
var numberDone = 0;
amqp.connect('amqp://localhost', { noDelay: false } ).then(function(conn) {
return when(conn.createChannel().then(function(ch) {
var q = 'hello';
var msg = 'Hello World!';
var ok = ch.assertQueue(q, {durable: false});
function sendMsg(){
ch.sendToQueue(q, new Buffer(msg));
console.log(" [x] Sent '%s'", msg, new Date().getTime());
numberDone++;
}
return ok.then(function(_qok) {
while(numberDone < numberToSend){
sendMsg();
}
console.log('*** done');
return ch.close();
});
})).ensure(function() { conn.close(); });
}).then(null, console.warn);
答案 0 :(得分:1)
节点是单线程的,因此无法处理任何传入的消息,直到完成所有发送的while
循环完成。
尝试将sendMsg
包裹在setImmediate
电话中,看看它如何改变(它必须转换为承诺并链接,以便频道和连接不会在一切都发送之前关闭):
function sendMsg(resolve){
setImmediate(function() {
ch.sendToQueue(q, new Buffer(msg));
console.log(" [x] Sent '%s'", msg, new Date().getTime());
resolve();
});
}
return ok.then(function(_qok) {
var sendOk = when.promise(sendMsg);
while(numberDone < numberToSend){
sendOk = sendOk.then(function() {
return when.promise(sendMsg);
});
numberDone++;
}
return sendOk.finally(function() {
console.log('*** done');
ch.close();
});
});
即使只有5条消息,您也可以看到差异:
[x] Sent 'Hello World!' 1428467734962
[*] Waiting for messages. To exit press CTRL+C
[x] Sent 'Hello World!' 1428467734963
1428467734965
[x] Received 'Hello World!' 1
[x] Sent 'Hello World!' 1428467734965
[x] Sent 'Hello World!' 1428467734965
[x] Sent 'Hello World!' 1428467734966
[x] Sent 'Hello World!' 1428467734966
*** done
1428467735004
[x] Received 'Hello World!' 2
1428467735005
[x] Received 'Hello World!' 3
1428467735005
[x] Received 'Hello World!' 4
1428467735005
[x] Received 'Hello World!' 5