Rabbit MQ amqplib error “No channels left to allocate”

今天在查看node.js服务日志的时候发现amqplib模块报错No channels left to allocate。是服务没有复用通道,创建了太多的channel导致该问题,通过调试找到报错的位置,在amqplib/lib/connection.jsfreshChannel函数中报错。
具体代码如下:

// I use an array to keep track of the channels, rather than an
// object. The channel identifiers are numbers, and allocated by the
// connection. If I try to allocate low numbers when they are
// available (which I do, by looking from the start of the bitset),
// this ought to keep the array small, and out of 'sparse array
// storage'. I also set entries to null, rather than deleting them, in
// the expectation that the next channel allocation will fill the slot
// again rather than growing the array. See
// http://www.html5rocks.com/en/tutorials/speed/v8/
C.freshChannel = function(channel, options) {
  var next = this.freeChannels.nextClearBit(1);
  if (next < 0 || next > this.channelMax)
    throw new Error("No channels left to allocate");
  this.freeChannels.set(next);
  //
  此处省略多行代码
  //
};

可以看出当创建的通道大于channelMax就会抛出该异常。而该channelMax的值是跟rabbitmq server协商来的。
调试在amqplib/lib/connection.jsafterStartOk函数,该函数用于根据服务器端传入的数据来设置channelMax,heartbeat等通讯参数,函数代码如下:

  function afterStartOk(reply) {
    switch (reply.id) {
    case defs.ConnectionSecure:
      bail(new Error(
        "Wasn't expecting to have to go through secure"));
      break;
    case defs.ConnectionClose:
      bail(new Error(fmt("Handshake terminated by server: %s",
                         closeMsg(reply))));
      break;
    case defs.ConnectionTune:
      var fields = reply.fields;//服务器段返回的通讯参数
      tunedOptions.frameMax =
        negotiate(fields.frameMax, allFields.frameMax);
      tunedOptions.channelMax =
        negotiate(fields.channelMax, allFields.channelMax);   //在这里设置最大通道数
      tunedOptions.heartbeat =
        negotiate(fields.heartbeat, allFields.heartbeat);
      send(defs.ConnectionTuneOk);
      send(defs.ConnectionOpen);
      expect(defs.ConnectionOpenOk, onOpenOk);
      break;
    default:
      bail(new Error(
        fmt("Expected connection.secure, connection.close, " +
            "or connection.tune during handshake; got %s",
            inspect(reply, false))));
      break;
    }
  }

在我这个环境下服务器返回的最大通道数为2047,由此最多可以创建2047个通道。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值