阅读更多
Connection and Timeout in RabbitMQ NodeJS
In our simple script, we are write a sendToQueue.js in NodeJS to send out JSON file content to RabbitMQ. I think we just follow the example in RabbitMQ and do it like this
// Usage: node sendToQueue.js meeting-to-update-stage.json
{
const amqp = require('amqplib/callback_api');
const fs = require('fs');
const durable = process.env.MQ_DURABLE || true;
const exchangeType = 'topic';
const exchange = ‘xxxxxx_events';
const amqpHost = 'amqp://username:
[email protected]/name?heartbeat=30';
const objectFile = process.argv[2];
let objects = fs.readFileSync(objectFile).toString().split("\n");
objects.forEach(msg => {
console.log(`parsed from file - ${JSON.stringify(msg)}\n`);
});
try {
console.log(`sending messages to rabbit... `);
amqp.connect(amqpHost, function (err, conn) {
conn.createChannel(function (err, ch) {
ch.assertExchange(exchange, exchangeType, { durable: durable });
objects.forEach(msg => {
if(msg !== null && msg !== '') {
ch.publish(exchange, '', Buffer.from(msg));
}
});
});
setTimeout(function () { conn.close(); process.exit(0) }, 500);});
} catch (error) {
console.log(`error: ${error}`);
}
}
The issue is setTimeout(xxx, 500); in the example, it only send out 1 message, wait 500 ms is good enough.
But in my case, it is a loop with thousands, hundreds messages. It is working when the number is 100, but not working when the number is 1000.
Here is the promise example I think, it fixed the timeout connection issue.
{
const amqp = require('amqplib');
const fs = require('fs');
const durable = process.env.MQ_DURABLE || true;
const exchangeType = 'topic';
const exchange = ‘xxxxxx_events';
const amqpHost = 'amqp://username:
[email protected]/name?heartbeat=30';
const objectFile = process.argv[2];
let objects = fs.readFileSync(objectFile).toString().split("\n");
(async () => {
try {
const conn = await amqp.connect(amqpHost);
const ch = await conn.createChannel();
await ch.assertExchange(exchange, exchangeType, { durable: durable });
console.log("Loading csv file contents, number of records = " + objects.length);
await objects.map(async (msg) => {
if(msg !== null && msg !== '') {
try {
console.log(`msg = ${JSON.stringify(msg)}\n`)
await ch.publish(exchange, '', Buffer.from(msg));
return msg;
} catch (error) {
console.log("**** ERROR processing msg: " + error);
}
}
});
await ch.close();
await conn.close();
} catch (error) {
console.log(error);
}
})()
}
Then it works perfectly.
References:
https://github.com/squaremo/amqp.node/issues/404
https://zhuanlan.zhihu.com/p/28276010
https://www.cnblogs.com/duhuo/p/6306535.html
https://stackoverflow.com/questions/41212249/node-wait-for-loop-to-finish
https://stackoverflow.com/questions/18574298/wait-until-node-amqp-has-sent-a-message