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#)

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

遗憾的是,服务器正在生产中运行,并且正在处理数千个请求,因此很难提供任何其他上下文.服务器的基本功能是为其他服务发出出站HTTP请求.

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

结束无限循环的另一个证据是事件循环本身似乎已停止.当我将一个console.log放在setInterval中时,服务器会在冻结时立即停止输出.

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

我们正在使用JSONStream 0.7.1(其中包含默认的jsonparse版本0.0.5).我们在JSONStream repo上找到了this issue,并尝试使用JSONParse,只更新到最新的jsonparse版本.它没有解决问题.

最佳答案 看来你的问题是由
this line的jsonstream@0.0.5引起的.虽然我无法在没有转储通过服务器的内容的情况下为您解决问题,但这似乎表明您的缓冲区非常大.

这也可以解释为什么你的服务器锁定(正如你在聊天中提到的),为什么事件循环不能继续以及为什么你的内存不会上升到天空而你的CPU呢?这里可能发生的事情是你试图toString()一个难以置信的大量字节,你的硬件根本无法做到而且它会死掉.

通过各种方式报告此领导的任何进一步调查.我觉得你不可避免地要在开发盒上重新调试这个问题.它可以简单到为缓冲区添加一些健全性检查并确保它不超过一定的大小.

只有当n <= 128时才会触及上面的代码段,所以如果你使用的是有符号字符(例如Unicode)或有符号字节,那么你可能在正常函数中遇到这个问题……可能需要考虑!

点赞