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