背景
使用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()}`);
    });
  });

分析原因

  1. node内存不足
  2. message object 没有尽早释放
  3. request没有结束,body里面的内容没有及时释放

解决办法

  1. 尝试 node --max_old_space_size=4096 main.js 增加内存。
    经过测试,发现的程序的确可以多占用一些内存,跑的久一点,但是最后还是崩了。
  2. 尝试 把JSON.stringify(message)提出来,用temp存放,然后把message设置为null, 希望gc能提前回收message。
    经过测试,发现效果不明显,程序依然崩溃。
  3. 设置request的timeout到1秒。
    经过测试,内存能回收了,程序运行了,但是python没有收到消息。
  4. 重构python的flask restful api, 使用tornado和flask混用方式,让python先返回结果,然后再执行task。
    经过测试, 程序内存维持稳定, 完美运行。

思考
如果内存不是持续的增长,而是某时刻一下需要比较大的内存,可以尝试使用上述解决办法#1;
如果是内存在持续增长,需要分析什么引起的,是因为没有及时释放内存还是因为内存泄露,比如闭包,定时器等。然后对症下药。
再想想#3还可能遇到的问题,首先是网络不好的情况,python返回慢了的依然会有问题。若是要解决其实应该用stream把messages整体一起传给python。但是因为现在我正处于封闭开发的阶段,没有时间去重构。


NicolasHe
325 声望11 粉丝

千日修以返初心,万日练以达极真