我的网站开发技术经验总结 我的网站开发技术经验总结
首页

fangdown

我的网站开发技术经验总结
首页
  • 大前端

    • nodejs

      • nodejs有哪些全局对象,怎么用
      • 如何在nodejs中实现分页机制功能
      • 如何在nodejs实现文件上传功能
      • 如何实现nodejs鉴权机制,说一下思路
      • 说说nodejs中require的原理
      • 说说nodejs中的EventEmit是如何实现的
      • 说说nodejs中的事件循环机制理解
      • 说说nodejs中进程通信有哪些方式
      • 说说nodejs中间件是什么,如何封装一个中间件
      • 说说对buffer的理解及应用场景
      • 说说对fs模块的理解及常用方法
      • 说说对nodejs的理解及应用场景
      • 说说对process的理解及常用方法
      • 说说对stream的理解及应用场景
      • nodejs如何进行性能监控及优化
        • 是什么
          • cpu
          • 内存
          • i/o
        • 如何监控
        • 如何优化
          • stream
          • 代码层面
          • 内存层面
        • FAQ
      • nodejs批量改文件名
    • git

    • CI

    • 小程序

    • docker

    • Typescript

    • webpack

    • 安全

  • 基础

  • 框架

  • 情商

  • 算法

  • 网络

  • 千锤百炼
  • 大前端
  • nodejs
fangdown
2021-08-17
目录

nodejs如何进行性能监控及优化

# 是什么

nodejs作为服务端语言,性能监控的衡量指标:

  • cpu
  • 内存
  • i/o
  • 网络

# cpu

  • cpu负载率:在某个时段内, 占用及等待cpu的进程总数
  • cpu使用率:1 - cpu空闲时间 / cpu总时间

Node应用一般不会消耗很多的CPU,如果CPU占用率高,则表明应用存在很多同步操作,导致异步任务回调被阻塞

# 内存

  • rss: node占用的内存总量
  • heapTotal : 堆内存量
  • heapUsed: 实际堆内存使用量
  • external: 外部程序的内存使用量

在node中一个进程最大内容容量为1.5G, 因此我们需要避免内存泄漏

// /app/lib/memory.js
const os = require('os');
// 获取当前Node内存堆栈情况
const { rss, heapUsed, heapTotal } = process.memoryUsage();
// 获取系统空闲内存
const sysFree = os.freemem();
// 获取系统总内存
const sysTotal = os.totalmem();

module.exports = {
  memory: () => {
    return {
      sys: 1 - sysFree / sysTotal,  // 系统内存占用率
      heap: heapUsed / headTotal,   // Node堆内存占用率
      node: rss / sysTotal,         // Node占用系统内存的比例
    }
  }
}

# i/o

内存io比磁盘io快很多, 推荐使用,如redis、memcached

# 如何监控

// 第三方插件
const easyMonitor = require('easy-monitor');
easyMonitor('你的项目名称');

http://localhost:12333 ,打开即可访问

# 如何优化

  • 使用最新版本nodejs
  • 正确使用stream
  • 代码层面优化
  • 内存管理优化

# stream

大文件占用内存

const http = require('http');
const fs = require('fs');

// bad
http.createServer(function (req, res) {
    fs.readFile(__dirname + '/data.txt', function (err, data) {
        res.end(data);
    });
});

// good
http.createServer(function (req, res) {
    const stream = fs.createReadStream(__dirname + '/data.txt');
    stream.pipe(res);
});

# 代码层面

合并

// bad
for user_id in userIds 
     let account = user_account.findOne(user_id)

// good
const user_account_map = {}   // 注意这个对象将会消耗大量内存。
user_account.find(user_id in user_ids).forEach(account){
    user_account_map[account.user_id] =  account
}
for user_id in userIds 
    var account = user_account_map[user_id]

# 内存层面

const buffer = fs.readFileSync(__dirname + '/source/index.htm');

app.use(
    mount('/', async (ctx) => {
        ctx.status = 200;
        ctx.type = 'html';
        ctx.body = buffer;
        leak.push(fs.readFileSync(__dirname + '/source/index.htm'));
    })
);

const leak = []; // 释放

# FAQ

#性能
上次更新: 2021/12/19, 18:05:42
说说对stream的理解及应用场景
nodejs批量改文件名

← 说说对stream的理解及应用场景 nodejs批量改文件名→

最近更新
01
多分支修复撞车的问题
05-01
02
如何成为架构师
01-23
03
服务器部署全过程
11-23
更多文章>
Theme by Vdoing | Copyright © 2019-2026 fangdown | 粤ICP备19079809号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式