We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Node作为一门服务端语言,性能方面尤为重要,其衡量指标一般有如下:
Node
主要分成了两部分:
这两个指标都是用来评估系统当前CPU的繁忙程度的量化指标
Node应用一般不会消耗很多的CPU,如果CPU占用率高,则表明应用存在很多同步操作,导致异步任务回调被阻塞
CPU
内存是一个非常容易量化的指标。 内存占用率是评判一个系统的内存瓶颈的常见指标。 对于Node来说,内部内存堆栈的使用状态也是一个可以量化的指标
// /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占用系统内存的比例 } } }
在Node中,一个进程的最大内存容量为1.5GB。因此我们需要减少内存泄露
硬盘的 IO 开销是非常昂贵的,硬盘 IO 花费的 CPU 时钟周期是内存的 164000 倍
IO
内存 IO 比磁盘 IO 快非常多,所以使用内存缓存数据是有效的优化方法。常用的工具如 redis、memcached 等
redis
memcached
并不是所有数据都需要缓存,访问频率高,生成代价比较高的才考虑是否缓存,也就是说影响你性能瓶颈的考虑去缓存,并且而且缓存还有缓存雪崩、缓存穿透等问题要解决
关于性能方面的监控,一般情况都需要借助工具来实现
这里采用Easy-Monitor 2.0,其是轻量级的 Node.js 项目内核性能监控 + 分析工具,在默认模式下,只需要在项目入口文件 require 一次,无需改动任何业务代码即可开启内核级别的性能监控分析
Easy-Monitor 2.0
Node.js
require
使用方法如下:
在你的项目入口文件中按照如下方式引入,当然请传入你的项目名称:
const easyMonitor = require('easy-monitor'); easyMonitor('你的项目名称');
打开你的浏览器,访问 http://localhost:12333 ,即可看到进程界面
http://localhost:12333
关于定制化开发、通用配置项以及如何动态更新配置项详见官方文档
关于Node的性能优化的方式有:
每个版本的性能提升主要来自于两个方面:
在Node中,很多对象都实现了流,对于一个大文件可以通过流的形式发送,不需要将其完全读入内存
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]
在 V8 中,主要将内存分为新生代和老生代两代:
若新生代内存空间不够,直接分配到老生代
通过减少内存占用,可以提高服务器的性能。如果有内存泄露,也会导致大量的对象存储到老生代中,服务器性能会大大降低
如下面情况:
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 = [];
leak的内存非常大,造成内存泄露,应当避免这样的操作,通过减少内存使用,是提高服务性能的手段之一
leak
而节省内存最好的方式是使用池,其将频用、可复用对象存储起来,减少创建和销毁操作
例如有个图片请求接口,每次请求,都需要用到类。若每次都需要重新new这些类,并不是很合适,在大量请求时,频繁创建和销毁这些类,造成内存抖动
使用对象池的机制,对这种频繁需要创建和销毁的对象保存在一个对象池中。每次用到该对象时,就取对象池空闲的对象,并对它进行初始化操作,从而提高框架的性能
The text was updated successfully, but these errors were encountered:
No branches or pull requests
一、 是什么
Node
作为一门服务端语言,性能方面尤为重要,其衡量指标一般有如下:CPU
主要分成了两部分:
这两个指标都是用来评估系统当前CPU的繁忙程度的量化指标
Node
应用一般不会消耗很多的CPU
,如果CPU
占用率高,则表明应用存在很多同步操作,导致异步任务回调被阻塞内存指标
内存是一个非常容易量化的指标。 内存占用率是评判一个系统的内存瓶颈的常见指标。 对于Node来说,内部内存堆栈的使用状态也是一个可以量化的指标
在
Node
中,一个进程的最大内存容量为1.5GB。因此我们需要减少内存泄露磁盘 I/O
硬盘的
IO
开销是非常昂贵的,硬盘 IO 花费的 CPU 时钟周期是内存的 164000 倍内存
IO
比磁盘IO
快非常多,所以使用内存缓存数据是有效的优化方法。常用的工具如redis
、memcached
等并不是所有数据都需要缓存,访问频率高,生成代价比较高的才考虑是否缓存,也就是说影响你性能瓶颈的考虑去缓存,并且而且缓存还有缓存雪崩、缓存穿透等问题要解决
二、如何监控
关于性能方面的监控,一般情况都需要借助工具来实现
这里采用
Easy-Monitor 2.0
,其是轻量级的Node.js
项目内核性能监控 + 分析工具,在默认模式下,只需要在项目入口文件require
一次,无需改动任何业务代码即可开启内核级别的性能监控分析使用方法如下:
在你的项目入口文件中按照如下方式引入,当然请传入你的项目名称:
打开你的浏览器,访问
http://localhost:12333
,即可看到进程界面关于定制化开发、通用配置项以及如何动态更新配置项详见官方文档
三、如何优化
关于
Node
的性能优化的方式有:使用最新版本Node.js
每个版本的性能提升主要来自于两个方面:
正确使用流 Stream
在
Node
中,很多对象都实现了流,对于一个大文件可以通过流的形式发送,不需要将其完全读入内存代码层面优化
合并查询,将多次查询合并一次,减少数据库的查询次数
内存管理优化
在 V8 中,主要将内存分为新生代和老生代两代:
若新生代内存空间不够,直接分配到老生代
通过减少内存占用,可以提高服务器的性能。如果有内存泄露,也会导致大量的对象存储到老生代中,服务器性能会大大降低
如下面情况:
leak
的内存非常大,造成内存泄露,应当避免这样的操作,通过减少内存使用,是提高服务性能的手段之一而节省内存最好的方式是使用池,其将频用、可复用对象存储起来,减少创建和销毁操作
例如有个图片请求接口,每次请求,都需要用到类。若每次都需要重新new这些类,并不是很合适,在大量请求时,频繁创建和销毁这些类,造成内存抖动
使用对象池的机制,对这种频繁需要创建和销毁的对象保存在一个对象池中。每次用到该对象时,就取对象池空闲的对象,并对它进行初始化操作,从而提高框架的性能
参考文献
The text was updated successfully, but these errors were encountered: