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 的性能

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进程线程优化性能的更多相关文章

  1. Mysql优化性能优化21条

    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据 ...

  2. python自动化开发学习 进程, 线程, 协程

    python自动化开发学习 进程, 线程, 协程   前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...

  3. CQRS之旅——旅程7(增加弹性和优化性能)

    旅程7:增加弹性和优化性能 到达旅程的终点:最后的任务. "你不能飞的像一只长着鹪鹩翅膀的老鹰那样."亨利·哈德逊 我们旅程的最后阶段的三个主要目标是使系统对故障更具弹性,提高UI ...

  4. 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型

    本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...

  5. android:布局、绘制、内存泄露、响应速度、listview和bitmap、线程优化以及一些优化的建议!

    1.布局优化 首先删除布局中无用的控件和层级,其次有选择地使用性能较低的viewgroup,比如布局中既可以使用RelativeLayout和LinearLayout,那我们就采用LinearLayo ...

  6. [skill] 进程 线程

    在业务逻辑上: 进程线程没有区别. 在系统资源上: 进程拥有自己的地址空间.线程拥有自己的堆栈和临时变量,与其他线程共享地址空间. 在通信代价上: 线程间通信代价更低,实现更方便.进程通信相对开销比较 ...

  7. [经验] Win7减肥攻略(删文件不删功能、简化优化系统不简优化性能)

    [经验] Win7减肥攻略(删文件不删功能.简化优化系统不简优化性能) ☆心梦无痕☆ 发表于 2014-1-24 11:15:04 https://www.itsk.com/thread-316471 ...

  8. pyhon——进程线程、与协程基础概述

    一直以来写博客都是实用主义者,只写用法,没信心写原理,但是每一次写作业的过程都有一种掘地三尺的感觉,终于,写博客困难症重症患者经历了漫长的思想斗争,还是决定把从网上淘到的各种杂货和自己的总结放在一起, ...

  9. android 进程/线程管理(二)----关于线程的迷思

    一:进程和线程的由来 进程是计算机科技发展的过程的产物. 最早计算机发明出来,是为了解决数学计算而发明的.每解决一个问题,就要打纸带,也就是打点. 后来人们发现可以批量的设置命令,由计算机读取这些命令 ...

随机推荐

  1. 论文笔记之:Natural Language Object Retrieval

    论文笔记之:Natural Language Object Retrieval 2017-07-10  16:50:43   本文旨在通过给定的文本描述,在图像中去实现物体的定位和识别.大致流程图如下 ...

  2. it做形式主语的句子

    1. it was considerate of you to visit my mother every day and (to) bring me your notes to help me wi ...

  3. Linux下使用wget下载FTP服务器文件

    wget -nH -m --ftp-user=your_username --ftp-password=your_password ftp://your_ftp_host/* 使用命令下载ftp上的文 ...

  4. Tengine(nginx) 搭建Tomcat集群

    好久没有更新学习的内容了,就是得强迫自己写点东西 记录自己的学习,才能更好的进步! Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和 ...

  5. 【译】第12节---数据注解-ConcurrencyCheck

    原文:http://www.entityframeworktutorial.net/code-first/concurrencycheck-dataannotations-attribute-in-c ...

  6. webpack插件配置(二)- HtmlWebpackPlugin

    作用 简化Html文件的创建,以便为你的webpack bundle包提供服务.这对于在文件名中包含每次会随着编译而发生变化的hash的webpack bundle尤其有用.插件可以生成一个HTML文 ...

  7. HashMap的实现原理-----哈希讲解

    哈希,英文名Hash.他就像是一个隔壁家的孩子一样,伴随着码工们的成长.听到他们的名字,我们都觉得很高大上. 在写程序的时候,一般我们都是这样被教育的:这个事情搞不定?用哈希呀! 在面试的时候,一般是 ...

  8. 关于在mac安装安卓的模拟器的一些些那点事情~~~

    ook~~自己捣鼓了三天终于安装成功了~妹的~踩了太多的坑~整个人就不好了~ 为了节省大家的时间~所以今天我就将我安装的过程整体思路教给大家!有了思路安装起来就很好了!!!但是 注意的是,也许你会出现 ...

  9. Vue运行报错--not defined

    按F12键进入调试模式,谷歌总是提示Uncaught ReferenceError: ——is not defined这个错误. 原来是因为虽然是传递的值,但是在函数传参的时候也要加引号,加上引号后就 ...

  10. JAVA9新特性——JShell使用笔记

    前言:JShell是java 9的新特性之一,由于在之前学校java8的lambda表达式的时候,就希望有这么一个可以交互的界面来快速响应编写的代码.刚好java9出来了,就对它把玩起来了... 内容 ...