Rabbit MQ amqplib error “No channels left to allocate”

匿名 (未验证) 提交于 2019-12-03 00:11:01

今天在查看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个通道。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!