是什么原因导致amqp.node从RabbitMQ服务器获取ECONNRESET?

时间:2015-11-24 23:36:16

标签: node.js rabbitmq

我有一个在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服务器配置文件中的握手timout选项更改为10000ms,但没有任何改变。

我与访客用户使用相同的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和其他库之间是否存在任何冲突,导致与服务器断开连接?我该怎么调试呢?

2 个答案:

答案 0 :(得分:3)

此错误与连接和频道有关。因此,在您的代码中,您创建了一个连接和通道,但没有关闭它们。当没有时,这会产生这个错误(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);

答案 1 :(得分:1)

ECONNRESET通常是网络错误,这意味着它与它尝试进行的TCP / IP连接强行断开连接。

您的项目可能以某种方式运行,无法正常打开TCP / IP连接,或者遇到防火墙或其他问题。

当用户名和密码错误时,我也看到了这个错误。我强烈建议您设置一个新的用户名和密码,并授予该用户对相关vhost的正确权限(在本例中为默认的vhost)。

除此之外......有时需要玩一些代码来弄清楚导致问题的原因。如果您在复制和复制时没有看到此问题粘贴到您的真实项目中,您的项目中可能还有其他因素阻止其正常工作。

...

P.S。我建议不要直接使用amqplib。它是一个伟大的驱动程序,但它上面有更好(更友好)的API层,使生活更轻松。例如,我最喜欢的是wascally,它使用了引擎盖下的amqplib。我在http://RabbitMQ4Devs.com

录制了关于所有这些内容的截屏视频