记一次node内存泄漏问题,关于node-fetch

882 阅读1分钟

记一次node内存泄漏问题,关于node-fetch

最近收到告警,反映node服务内存过高。之前服务都是正常的,如果没有内存泄漏的情况的话,内存是不会过高的

经过一番排查(主要是看最近上的代码),发现是 node-fetch 引起的

问题起因

用node-fetch确认一下 某个url 是否存在,造成内存泄漏

// 如果此处 import报错,说明node版本低。低版本node可以在package.json里面加 "type": "module"
import Koa from 'koa';
const app = new Koa();
import fetch from 'node-fetch';

app.use(async function(ctx) {
  (async () => {
    fetch('https://t7.baidu.com/it/u=963301259,1982396977&fm=193&f=GIF') // 默认get请求
      .then(res => {
        console.log('exist');
      })
      .catch(err => {
        console.error(err);
      });
  })();

  ctx.body = 'Hello World';
});

app.listen(3000);

压测,及结果

用ab压测,ab -n1000 -c10  "http://localhost:3000/"

  • 并发10,请求1000次,结果:90分位请求耗时 327ms(响应较慢)
  • 内存泄漏 22.3M

oom.jpeg

解决办法

泄漏的原因是

node-fetch 有个bug github.com/node-fetch/…

  • 当你用node-fetch时,因为没用到response.body 导致内存泄漏

解法

把get请求,换成head请求

import Koa from 'koa';
const app = new Koa();
import fetch from 'node-fetch';

app.use(async function(ctx) {
  (async () => {
    fetch('https://t7.baidu.com/it/u=963301259,1982396977&fm=193&f=GIF', {
      method: 'HEAD'  // 换成HEAD请求
    })
      .then(res => {
        console.log('exist');
      })
      .catch(err => {
        console.error(err);
      });
  })();

  ctx.body = 'Hello World';
});

app.listen(3000);

压测,及结果

用ab压测,ab -n1000 -c10  "http://localhost:3000/"

  • 并发10,请求1000次,结果:90分位请求耗时 87ms(响应很快)
  • 内存泄漏正常回收,无泄漏 oom2.jpeg

码字不易,点赞鼓励!