nodejs进程线程优化性能
1. node.js 单线程的特点
node.js 以异步非阻塞单线程,作为其执行速度的保障。什么是非阻塞单线程?
举一个现实生活中的例子,我去巢大食堂打饭,我选择了A套餐,然后工作人员区为我配餐,我就在旁边等着直到阿姨叫号然后我取餐。这个过程是同步。
如果工作人员在为我配餐的同时,仍然可以接受排在我后面的同学的点餐,这样餐厅并没有因为我在等待A套餐而停止。这个过程是非阻塞。
如果我在阿姨为我配餐的同时,我去旁边小超市买了杯冷饮,等阿姨叫号时我再去取餐。这个过程就是异步非阻塞,同时阿姨叫号我去取餐的行为叫做回调。
- 高性能(不用考虑多线程间来回调用引起性能的损耗)
- 线程安全(不用担心同意变量会被多线程进行读写而造成程序的崩溃)
- 底层多线程
说node.js 是单线程其实也是不全面的,node.js 底层库会使用libuv调用多线程来处理I/O 操作。这就像食堂只有一个窗口,只能有按顺序一个个的接收点餐,但是后厨配菜的员工却有很多,他们各司其职保证出餐的速度。
如果服务器是多核且有充足的物理资源,如何充分发挥这些物理资源达到性能最大化。既食堂后厨有很多大师傅,一个窗口售卖的速度太慢,许多大师傅都是空闲的窗台。邪恶的资本家你们懂的?
2.如何通过多线程提高node.js 的性能
- cluster: 为了利用多核系统,用户有时会想启动一个 Node.js 进程的集群去处理负载。
const Koa = require('Koa');
const koaRouter = require('koa-router');
const app = new Koa();
const router = new koaRouter();
function fibo(n) {
return n > 1 ? fibo(n - 1) + fibo(n-2) : 1
}
app.use(router['routes']());
router.get('/', function(ctx, next) {
var result = fibo(35);
ctx.body = `${result}`;
});
if (!module.parent) {
app.listen(8080);
console.log(`Server was start.`);
}
通过ab 压力测试命令:
ab -c 20 -n 100 http://localhost:8080/
没有经过cluster 集群优化:
Server Software:
Server Hostname: localhost
Server Port: 8080
Document Path: /
Document Length: 8 bytes
Concurrency Level: 20
Time taken for tests: 13.569 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 14300 bytes
HTML transferred: 800 bytes
Requests per second: 7.37 [#/sec] (mean)
Time per request: 2713.723 [ms] (mean)
Time per request: 135.686 [ms] (mean, across all concurrent requests)
Transfer rate: 1.03 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 1
Processing: 155 2465 622.9 2738 2762
Waiting: 153 2465 623.0 2737 2762
Total: 155 2465 622.8 2738 2762
Percentage of the requests served within a certain time (ms)
50% 2738
66% 2743
75% 2746
80% 2747
90% 2753
95% 2757
98% 2761
99% 2762
100% 2762 (longest request)
通过cluster 集群优化后:
const Koa = require('Koa');
const koaRouter = require('koa-router');
const numCpus = require('os').cpus().length;
const cluster = require('cluster');
const app = new Koa();
const router = new koaRouter();
if (cluster.isMaster) {
console.log(`${numCpus}`);
for (var index = 0; index < numCpus; index++) {
cluster.fork();
}
} else {
app.use(router['routes']());
router.get('/', function(ctx, next) {
var result = fibo(35);
ctx.body = `${result}`;
});
if (!module.parent) {
app.listen(8080);
console.log(`Server was start.`);
}
}
function fibo(n) {
return n > 1 ? fibo(n - 1) + fibo(n-2) : 1
}
通过ab 压力测试命令:
ab -c 20 -n 100 http://localhost:8080/
Server Software:
Server Hostname: localhost
Server Port: 8080
Document Path: /
Document Length: 8 bytes
Concurrency Level: 20
Time taken for tests: 6.513 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 14300 bytes
HTML transferred: 800 bytes
Requests per second: 15.35 [#/sec] (mean)
Time per request: 1302.524 [ms] (mean)
Time per request: 65.126 [ms] (mean, across all concurrent requests)
Transfer rate: 2.14 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.5 0 2
Processing: 279 1198 258.7 1294 1335
Waiting: 279 1198 258.7 1294 1335
Total: 281 1198 258.3 1295 1335
Percentage of the requests served within a certain time (ms)
50% 1295
66% 1301
75% 1303
80% 1308
90% 1322
95% 1328
98% 1333
99% 1335
100% 1335 (longest request)
对比两次的测试结果:
优化后,
Requests per second (每秒处理的任务数) 由 7.37 提高到 15.35.
Time per request (每个用户的平均处理时间) 由 135.686 降低到 65.126
3. 如何通过多进程提高node.js 的性能
- Child Process 创建进程
main.js
const Koa = require('Koa');
const koaRouter = require('koa-router');
const fork = require('child_process').fork;
const app = new Koa();
const router = new koaRouter();
app.use(router['routes']());
router.get('/', function(ctx, next) {
var worker = fork('./work_fibo.js');
worker.on('message', function(m) {
if ('object' === typeof m && m.type === 'fibo') {
worker.kill();
ctx.body = m.result.toString();
}
});
worker.send({type: "fibo", num: 35}, (err) => {
console.log(`${err}`);
});
console.log(`${worker.pid}`);
});
if (!module.parent) {
app.listen(8080);
console.log(`Server was start.`);
}
work_fibo.js
var fibo = function fibo(n) {
return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
}
process.on('message', function(m) {
if (typeof m === 'object' && m.type === 'fibo') {
var num = fibo(m.num);
process.send({type: 'fibo', result: num});
}
});
process.on('SIGHUP', function() {
process.exist();
});
通过ab 压力测试命令:
ab -c 20 -n 100 http://localhost:8080/
Server Software:
Server Hostname: localhost
Server Port: 8080
Document Path: /
Document Length: 9 bytes
Concurrency Level: 20
Time taken for tests: 3.619 seconds
Complete requests: 100
Failed requests: 0
Non-2xx responses: 100
Total transferred: 15100 bytes
HTML transferred: 900 bytes
Requests per second: 27.63 [#/sec] (mean)
Time per request: 723.764 [ms] (mean)
Time per request: 36.188 [ms] (mean, across all concurrent requests)
Transfer rate: 4.07 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 4.5 0 43
Processing: 21 611 270.7 650 1134
Waiting: 18 610 270.7 649 1132
Total: 22 612 270.2 652 1134
Percentage of the requests served within a certain time (ms)
50% 652
66% 744
75% 794
80% 835
90% 958
95% 1054
98% 1122
99% 1134
100% 1134 (longest request)
对比两次的测试结果:
优化后,
Requests per second (每秒处理的任务数) 由 7.37 提高到 15.35 最后通过进程优化后达到 27.63
Time per request (每个用户的平均处理时间) 由 135.686 降低到 65.126 最后通过进程优化后达到 36.188
转载:https://www.jianshu.com/p/f25388f030be
nodejs进程线程优化性能的更多相关文章
- Mysql优化性能优化21条
今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据 ...
- python自动化开发学习 进程, 线程, 协程
python自动化开发学习 进程, 线程, 协程 前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...
- CQRS之旅——旅程7(增加弹性和优化性能)
旅程7:增加弹性和优化性能 到达旅程的终点:最后的任务. "你不能飞的像一只长着鹪鹩翅膀的老鹰那样."亨利·哈德逊 我们旅程的最后阶段的三个主要目标是使系统对故障更具弹性,提高UI ...
- 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型
本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...
- android:布局、绘制、内存泄露、响应速度、listview和bitmap、线程优化以及一些优化的建议!
1.布局优化 首先删除布局中无用的控件和层级,其次有选择地使用性能较低的viewgroup,比如布局中既可以使用RelativeLayout和LinearLayout,那我们就采用LinearLayo ...
- [skill] 进程 线程
在业务逻辑上: 进程线程没有区别. 在系统资源上: 进程拥有自己的地址空间.线程拥有自己的堆栈和临时变量,与其他线程共享地址空间. 在通信代价上: 线程间通信代价更低,实现更方便.进程通信相对开销比较 ...
- [经验] Win7减肥攻略(删文件不删功能、简化优化系统不简优化性能)
[经验] Win7减肥攻略(删文件不删功能.简化优化系统不简优化性能) ☆心梦无痕☆ 发表于 2014-1-24 11:15:04 https://www.itsk.com/thread-316471 ...
- pyhon——进程线程、与协程基础概述
一直以来写博客都是实用主义者,只写用法,没信心写原理,但是每一次写作业的过程都有一种掘地三尺的感觉,终于,写博客困难症重症患者经历了漫长的思想斗争,还是决定把从网上淘到的各种杂货和自己的总结放在一起, ...
- android 进程/线程管理(二)----关于线程的迷思
一:进程和线程的由来 进程是计算机科技发展的过程的产物. 最早计算机发明出来,是为了解决数学计算而发明的.每解决一个问题,就要打纸带,也就是打点. 后来人们发现可以批量的设置命令,由计算机读取这些命令 ...
随机推荐
- 【sql server】索引详解
索引可以理解为一种特殊的目录结构. sql server提供两种索引形式: 聚集索引和非聚集索引. 怎么理解这两种形式. 拿我们常用的字典举例来说, 一个字典好比数据库中的一个表.那么当我们想从字典中 ...
- spring 配置事务xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- 原生js仿jquery一些常用方法
原生js仿jquery一些常用方法 下面小编就为大家带来一篇原生js仿jquery一些常用方法(必看篇).小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 最近迷上了原 ...
- 3、My Scripts
.用for循环批量修改文件扩展名(P240) .使用专业改名命令rename来实现 .通过脚本实现sshd.rsyslog.crond.network.sysstat服务在开机时自动启动(P244) ...
- HDU 5236 Article(概率DP)
http://acm.hdu.edu.cn/showproblem.php?pid=5236 题意:现在有人要在文本编辑器中输入n个字符,然而这个编辑器有点问题. 在i+0.1s(i>=0)的时 ...
- Ubuntu ls: cannot open directory .: Permission denied
把该目录赋予权限: sudo chmod xxx
- maven 打包不同环境
支持不同环境打包 1 pom添加如下配置: 1)添加指定打包id 区分各个环境 <profiles> <profile> <id>dev</id> &l ...
- 异常处理.VC++
ZC:个人这样 理解 C++的异常处理: ZC: (1).C++标准异常处理,try{}catch{} 抛异常:throw() [ 据说是包装的Windows函数RaiseException() ] ...
- 结合CRT与欧拉定理高阶幂求余
- asp.net 虹软人脸识别sdk 释放内存
初始化时申请内存,用完记得释放,不然就会报“内存已满”的. 使用时: pMem = Marshal.AllocHGlobal(detectSize); 释放内存: Marshal.FreeHGloba ...