Node.js 性能:检测内存泄漏和高 CPU 使用率

问题描述 投票:0回答:1

我编写了一个 Node.js API,可以从集合中读取数据。包含 1000 条记录的集合。每条记录包含 300 个子负载数据点。

const data = await csvModel['csvFiles'].find({ "created_datetime": today_datetime });
if (data.length > 0) {
    for (let mappData of data) {
        await payloadMapping(mappData.payload);
    }
}

在payloadMapping内部,我们正在进行字段映射并存储在新集合中

const payloadMapping = async (jsonPayload) => {
  try {
      let categoryId = await getCategoryID(jsonPayload["category"][0].parent_category);
      let totalEvent = jsonPayload["category"][0].event.length;
      if (categoryId) {
          let allExistingEvent = await getAllEvents(categoryId);
          let eventInsertData = [];
          for (let i = 0; i < totalEvent; i++) {
              let duplicate_event = false;
              let eventPayload = {};
              eventPayload["categoryId"] = categoryId;
              eventPayload["start"] = jsonPayload["category"][0].event[i].start;
              /*Check no two event at same times */
              if (allExistingEvent.length > 0) {
                  allExistingEvent.forEach(item => {
                      let result = item.categoryId.every((element, index) => element === categoryId[index]);
                      if (result && item.start === eventPayload.start) {
                          duplicate_event = true;
                      }
                  });
              }
              /*Check ends */
              if (!duplicate_event) {
                  eventPayload["title"] = jsonPayload["category"][0].event[i].title;
                  eventPayload["description"] = jsonPayload["category"][0].event[i].description;
                  eventPayload["event_location"] = jsonPayload["category"][0].event[i].location;
                  eventPayload["duration"] = jsonPayload["category"][0].event[i].duration;
                  eventPayload["status"] = 1;
                  eventInsertData.push(eventPayload);
              }
          }
          if (eventInsertData.length > 0) {
            try {
                await Events.insertMany(eventInsertData);
            } catch (mongoErr) {
              console.log(mongoErr);
            }
          }
      } else {
        console.log("Category collection not exist" + jsonPayload["category"][0].name);
      }
    } catch (error) {
    console.log(error, "catch error")
  }
}

此函数根据parent_category列出所有事件

const getCategoryID = (parent_category) => {
  return new Promise( (resolve) => {
    (async () => {
      const query = { parent_category: parent_category};
      let categoryArray = [];
      let categoryResult = await categoryModel.find(query);
      if (categoryResult.length > 0) {
        categoryResult.forEach((item) => {
          categoryArray.push(item._id.toString());
        })
      }
      resolve(categoryArray);
    });
  });
};

此函数根据category_id列出所有事件

const getAllEvents = (categoryId) => {
  return new Promise( (resolve) => {
    (async () => {
      try {
        const eventLists = await Events.find({ 'categoryId': categoryId }, { "categoryId": 1, "start": 1 });
        if (eventLists.length > 0) {
          resolve(eventLists);
        } else {
          resolve([]);
        }
      } catch (dbErr) {
        console.log("dbErr", dbErr);
        resolve([]);
      }
    });
  });
};

我已经给POD提供了以下配置

资源限制

资源: 要求:

内存:“250Mi”, 中央处理器:“50m”,

限制: 内存:“8000Mi” 中央处理器:“4000m”

运行 API 时,我的内存和 CPU 利用率很高。请帮我优化代码。

javascript node.js asynchronous
1个回答
0
投票

一些注意事项:

  • 每次调用
    getCategoryID
    getAllEvents
    都可能生成一个 新的数据库查询。通过批处理最小化查询数量 操作或重构数据的检索和处理方式。
  • 确保您的 MongoDB 集合在字段上有适当的索引 经常查询的(parent_category、categoryId 等)。这 可以大大减少每次查询所花费的时间,从而减少 CPU 使用率。
  • 如果可能,对数据库查询进行分页以避免加载所有 立即记录到内存中。这可以帮助更多地管理内存使用 有效。
  • 您将
    new Promise
    与立即调用的异步函数一起使用
    getCategoryID
    getAllEvents
    内部是不必要的,因为异步 函数已经返回一个承诺。将这些函数简化为 直接返回查询结果。
  • Node.js 内置分析器 (node --inspect)、Chrome 等工具 开发者工具,或专用的 NPM 包,例如 memwatch-next 和 heapdump 可以帮助识别内存泄漏。
  • 确保异步处理 CPU 密集型任务,以防止 阻塞事件循环。考虑使用工作线程来处理繁重的任务 计算任务。

以下是重构 getCategoryID 以进行简化的方法:

const getCategoryID = async (parent_category) => {
  try {
    const query = { parent_category: parent_category };
    const categoryResult = await categoryModel.find(query);
    return categoryResult.map(item => item._id.toString());
  } catch (error) {
    console.error("Error fetching category ID:", error);
    return [];
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.