node.js – JSONStream期间的无限循环

我有一个在生产中冻结的node.js服务器,它似乎是由JSONStream内部的无限循环引起的。 以下是从冻结服务器的核心转储中捕获的​​堆栈跟踪:

1: toString [buffer.js:~392] (this=0x1e28fb6d25c9 <a Buffer>#1#,encoding=0x266ee104121 <undefined>,start=0x266ee104121 <undefined>,end=0x266ee104121 <undefined>) 2: arguments adaptor frame: 0->3 3: write [/home/deploy/node_modules/JSONStream/node_modules/jsonparse/jsonparse.js:136] (this=0x32cc8dd5a999 <a Parser>#2#,buffer=0x32cc8dd5aa49 <a Buffer>#3#) 4: /* anonymous */ [/home/deploy/node_modules/JSONStream/index.js:~17] (this=0x32cc8dd5ab11 <a Stream>#4#,chunk=0x32cc8dd5aa49 <a Buffer>#3#) 5: write [/home/deploy/node_modules/JSONStream/node_modules/through/index.js:~24] (this=0x32cc8dd5ab11 <a Stream>#4#,data=0x32cc8dd5aa49 <a Buffer>#3#) 6: write [_stream_readable.js:~582] (this=0x266ee106c91 <JS Global Object>#5#,dest=0x32cc8dd5ab11 <a Stream>#4#,i=0,list=0x266ee104101 <null>) 7: flow [_stream_readable.js:592] (this=0x266ee106c91 <JS Global Object>#5#,src=0x32cc8dd5ac69 <an IncomingMessage>#6#) 8: /* anonymous */ [_stream_readable.js:560] (this=0x266ee106c91 <JS Global Object>#5#) 9: _tickCallback [node.js:415] (this=0x29e7331bb2a1 <a process>#7#) 

我怎样才能find这个无限循环的来源?

不幸的是,服务器正在运行,正在处理数千个请求,所以很难给出任何额外的上下文。 服务器的基本function是为其他服务发出HTTP请求。

值得注意的是我不相信这是由内存泄漏造成的。 在这些冻结事件期间,服务器的内存使用量保持不变(和低),而CPU高达99%

另外一个certificate无限循环的证据是事件循环本身似乎已经停止了。 当我把一个console.log放在一个setInterval里时,服务器一停止就会停止输出。

我们已经证实,这个问题不是由过期的/损坏的套接字连接引起的,通过设置最大连接数为Infinity(禁止在node.js中重用)

我们正在使用JSONStream 0.7.1(其中包括0.0.5的默认jsonparse版本)。 我们在JSONStream仓库中发现了这个问题 ,并尝试了分叉JSONParse,只更新到最新的jsonparse版本。 它没有解决这个问题。

看来你的问题在某种程度上是由jsonstream@0.0.5的这一行引起的。 虽然我不能确定地解决这个问题,但是没有经过服务器的转储,这似乎表明您的缓冲区非常大。

这也解释了为什么你的服务器被locking了(就像你在聊天中提到的那样),为什么事件循环没有进行,为什么你的内存不能上到天空,但是你的CPU呢? 这里可能发生的是你正在尝试toString()一个难以置信的大量的字节,你的硬件根本无法做,并死亡。

通过一切手段报告这个领导的进一步调查。 我觉得这是不可避免的,你将有一个开发盒重现这个问题。 这可能就像为你的缓冲区增加一些理智检查一样简单,并确保它不会超过一定的大小。

上面的代码段只有在n <= 128时才会被n <= 128 ,所以如果你使用的是有符号的字符(比如Unicode)或者有符号的字节,那么你可能在正常的函数中遇到了这个问题。