是什么导致 amqp.node 从 RabbitMQ 服务器获取 ECONNRESET?
What causes amqp.node to get ECONNRESET from a RabbitMQ server?
我在 Windows 8 环境中有一个 RabbitMQ 实例(默认配置)运行。我的节点版本是 5.1.0,我正在尝试使用 amqp.node 库在它们之间建立连接以传递消息。
当我尝试示例代码时:
var q = 'tasks';
function bail(err) {
console.error(err);
process.exit(1);
}
// Publisher
function publisher(conn) {
conn.createChannel(on_open);
function on_open(err, ch) {
if (err != null) bail(err);
ch.assertQueue(q);
ch.sendToQueue(q, new Buffer('something to do'));
}
}
// Consumer
function consumer(conn) {
var ok = conn.createChannel(on_open);
function on_open(err, ch) {
if (err != null) bail(err);
ch.assertQueue(q);
ch.consume(q, function(msg) {
if (msg !== null) {
console.log(msg.content.toString());
ch.ack(msg);
}
});
}
}
require('amqplib/callback_api')
.connect('amqp://guest:guest@localhost:5672', function(err, conn) {
if (err != null) bail(err);
consumer(conn);
publisher(conn);
});
我让它工作正常。
但是,如果我将这段代码(原样)移到我的项目中,则会出现此错误:
ECCONRESET 系统调用:读取。
我的应用程序使用 express.js 和 oauth2.0 运行。即使我将代码放在任何其他语句和模块的要求之前,它也不起作用。
我搜索了这个错误,发现了一些与负载平衡相关的问题,但我在本地运行它并且示例代码工作正常。
我发现的另一个问题可能与 TCP 连接有关,我将 RabbitMQ 服务器配置文件中的握手超时选项更改为 10000 毫秒,但没有任何改变。
我对来宾用户使用相同的 url:amqp://guest:guest@localhost:5672,它适用于示例代码。
来自 RabbitMQ 的日志显示连接已完成,但几秒钟后,它指出连接意外关闭:
=INFO REPORT==== 24-Nov-2015::18:09:52 ===
accepting AMQP connection <0.2644.0> (127.0.0.1:51866 -> 127.0.0.1:5672)
=ERROR REPORT==== 24-Nov-2015::18:10:12 ===
closing AMQP connection <0.2644.0> (127.0.0.1:51866 -> 127.0.0.1:5672):
{handshake_timeout,frame_header}
所以我的问题是:amqp.node 和其他断开与服务器连接的库之间是否存在任何冲突?我该如何调试?
ECONNRESET 通常是网络错误,这意味着它被强制断开了它试图建立的 TCP/IP 连接。
您的项目可能 运行 以某种方式阻止它正确打开 TCP/IP 连接,或者遇到防火墙或其他问题。
当用户名和密码错误时,我也看到过此错误。我强烈建议您设置一个新的用户名和密码,并授予该用户对相关虚拟主机(在本例中为默认虚拟主机)的正确权限。
除此之外...有时需要花一些时间研究代码才能找出导致问题的原因。如果您在复制并粘贴到您的真实项目中时没有看到此问题,则您的项目中可能有其他原因阻止它工作。
...
P.S。我建议不要直接使用 amqplib。这是一个很棒的驱动程序,但在它之上有更好(更友好)的 API 层,让生活更轻松。比如我最喜欢的是wascally which uses amqplib under the hood. I've recorded screencasts about all this, at http://RabbitMQ4Devs.com
此错误与连接和通道有关。因此,在您的代码中,您正在创建一个连接和通道,但没有关闭它们。这会在没有时创建此错误(ECONNRESET)。连接和通道限制耗尽 RabbitMQ 将停止接受新的网络连接。关闭通道和连接将解决此错误。示例代码:
amqp.connect('amqp://localhost')
.then(function(conn) {
return when(conn.createChannel().then(function(ch) {
var q = 'hello';
var msg = 'Hello World!';
var ok = ch.assertQueue(q, {durable: true});
return ok.then(function(_qok) {
ch.sendToQueue(q, new Buffer(msg), {deliveryMode: true});
console.log(" [x] Sent '%s'", msg);
return ch.close();
});
})).ensure(function() {
conn.close();
});
})
.then(null, console.warn);
我在 Windows 8 环境中有一个 RabbitMQ 实例(默认配置)运行。我的节点版本是 5.1.0,我正在尝试使用 amqp.node 库在它们之间建立连接以传递消息。
当我尝试示例代码时:
var q = 'tasks';
function bail(err) {
console.error(err);
process.exit(1);
}
// Publisher
function publisher(conn) {
conn.createChannel(on_open);
function on_open(err, ch) {
if (err != null) bail(err);
ch.assertQueue(q);
ch.sendToQueue(q, new Buffer('something to do'));
}
}
// Consumer
function consumer(conn) {
var ok = conn.createChannel(on_open);
function on_open(err, ch) {
if (err != null) bail(err);
ch.assertQueue(q);
ch.consume(q, function(msg) {
if (msg !== null) {
console.log(msg.content.toString());
ch.ack(msg);
}
});
}
}
require('amqplib/callback_api')
.connect('amqp://guest:guest@localhost:5672', function(err, conn) {
if (err != null) bail(err);
consumer(conn);
publisher(conn);
});
我让它工作正常。
但是,如果我将这段代码(原样)移到我的项目中,则会出现此错误:
ECCONRESET 系统调用:读取。
我的应用程序使用 express.js 和 oauth2.0 运行。即使我将代码放在任何其他语句和模块的要求之前,它也不起作用。
我搜索了这个错误,发现了一些与负载平衡相关的问题,但我在本地运行它并且示例代码工作正常。
我发现的另一个问题可能与 TCP 连接有关,我将 RabbitMQ 服务器配置文件中的握手超时选项更改为 10000 毫秒,但没有任何改变。
我对来宾用户使用相同的 url:amqp://guest:guest@localhost:5672,它适用于示例代码。
来自 RabbitMQ 的日志显示连接已完成,但几秒钟后,它指出连接意外关闭:
=INFO REPORT==== 24-Nov-2015::18:09:52 ===
accepting AMQP connection <0.2644.0> (127.0.0.1:51866 -> 127.0.0.1:5672)
=ERROR REPORT==== 24-Nov-2015::18:10:12 ===
closing AMQP connection <0.2644.0> (127.0.0.1:51866 -> 127.0.0.1:5672):
{handshake_timeout,frame_header}
所以我的问题是:amqp.node 和其他断开与服务器连接的库之间是否存在任何冲突?我该如何调试?
ECONNRESET 通常是网络错误,这意味着它被强制断开了它试图建立的 TCP/IP 连接。
您的项目可能 运行 以某种方式阻止它正确打开 TCP/IP 连接,或者遇到防火墙或其他问题。
当用户名和密码错误时,我也看到过此错误。我强烈建议您设置一个新的用户名和密码,并授予该用户对相关虚拟主机(在本例中为默认虚拟主机)的正确权限。
除此之外...有时需要花一些时间研究代码才能找出导致问题的原因。如果您在复制并粘贴到您的真实项目中时没有看到此问题,则您的项目中可能有其他原因阻止它工作。
...
P.S。我建议不要直接使用 amqplib。这是一个很棒的驱动程序,但在它之上有更好(更友好)的 API 层,让生活更轻松。比如我最喜欢的是wascally which uses amqplib under the hood. I've recorded screencasts about all this, at http://RabbitMQ4Devs.com
此错误与连接和通道有关。因此,在您的代码中,您正在创建一个连接和通道,但没有关闭它们。这会在没有时创建此错误(ECONNRESET)。连接和通道限制耗尽 RabbitMQ 将停止接受新的网络连接。关闭通道和连接将解决此错误。示例代码:
amqp.connect('amqp://localhost')
.then(function(conn) {
return when(conn.createChannel().then(function(ch) {
var q = 'hello';
var msg = 'Hello World!';
var ok = ch.assertQueue(q, {durable: true});
return ok.then(function(_qok) {
ch.sendToQueue(q, new Buffer(msg), {deliveryMode: true});
console.log(" [x] Sent '%s'", msg);
return ch.close();
});
})).ensure(function() {
conn.close();
});
})
.then(null, console.warn);