背景
使用nodejs的request向python的flask rest api放送大量的请求导致的”heap out of memory”。
messages.forEach((message)=>{
request({
url: url,
method: 'POST',
json: true,
body: JSON.stringify(message),
}).on('end', ()=>{
server.logger.info('End');
}).on('error', (err) => {
server.logger.error(`Error:${err.toString()}`);
});
});
分析原因
- node内存不足
- message object 没有尽早释放
- request没有结束,body里面的内容没有及时释放
解决办法
- 尝试 node –max_old_space_size=4096 main.js 增加内存。
经过测试,发现的程序的确可以多占用一些内存,跑的久一点,但是最后还是崩了。 - 尝试 把JSON.stringify(message)提出来,用temp存放,然后把message设置为null, 希望gc能提前回收message。
经过测试,发现效果不明显,程序依然崩溃。 - 设置request的timeout到1秒。
经过测试,内存能回收了,程序运行了,但是python没有收到消息。 - 重构python的flask restful api, 使用tornado和flask混用方式,让python先返回结果,然后再执行task。
经过测试, 程序内存维持稳定, 完美运行。
思考
如果内存不是持续的增长,而是某时刻一下需要比较大的内存,可以尝试使用上述解决办法#1;
如果是内存在持续增长,需要分析什么引起的,是因为没有及时释放内存还是因为内存泄露,比如闭包,定时器等。然后对症下药。
再想想#3还可能遇到的问题,首先是网络不好的情况,python返回慢了的依然会有问题。若是要解决其实应该用stream把messages整体一起传给python。但是因为现在我正处于封闭开发的阶段,没有时间去重构。