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 进程/线程管理(二)----关于线程的迷思
一:进程和线程的由来 进程是计算机科技发展的过程的产物. 最早计算机发明出来,是为了解决数学计算而发明的.每解决一个问题,就要打纸带,也就是打点. 后来人们发现可以批量的设置命令,由计算机读取这些命令 ...
随机推荐
- 【特性】MySQL 8 新特性
MySQL 8.0 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能! 注意:从 MySQL 5.7 升级到 MySQL 8 ...
- Java 字符串拆分(拆分字符串)
String sourceStr = "1,2,3,4,5"; String[] sourceStrArray = sourceStr.split(","); ...
- P3833 [SHOI2012]魔法树
思路 树剖板子 注意给出点的编号是从零开始的 代码 #include <cstdio> #include <algorithm> #include <cstring> ...
- (转)Awsome Domain-Adaptation
Awsome Domain-Adaptation 2018-08-06 19:27:54 This blog is copied from: https://github.com/zhaoxin94/ ...
- [蓝桥] 算法训练 P0505
时间限制:1.0s 内存限制:256.0MB 一个整数n的阶乘可以写成n!,它表示从1到n这n个整数的乘积.阶乘的增长速度非常快,例如,13!就已经比较大了,已经无法存放在一个整型变量中:而35!就更 ...
- python运维小技巧
以下实验均在Linux上进行 1.一秒钟启动一个下载服务器 python版本 python2: #python -m SimpleHTTPServer Serving HTTP on 0.0.0.0 ...
- 【Python】【网络编程】
#[[网络编程]] # 网络通信就是两个进程之间在通信 # [TCP/IP]'''TCP/IP简介 阅读: 125242虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联 ...
- 关于js中splice方法返回的结果
一.前言 刚刚在使用splice()方法,发现这个方法返回的是删除后的数组元素,如果要获取删除指定元素后的数组,直接调用原来的数组即可!因为splice()会改变原来数组!之前对splice()方法一 ...
- (总结)CentOS 6.x使用yum快速安装Apache+PHP+Tomcat(JSP)+MySQL
(总结)CentOS 6.x使用yum快速安装Apache+PHP+Tomcat(JSP)+MySQL PS:这个是懒人yum快速安装法,用于开发和测试环境很方便,用于没有特殊要求的生产环境也可以.特 ...
- 设计模式(三)Singleton Pattern单例设计模式
1.饿汉式 public class SingletonDemo { private static SingletonDemo s=new SingletonDemo(); private Singl ...