I/O 到底有什么效果和为什么能提高并发处理能力?
Node.js 不善于处理 CPU 密集型的业务,就会导致性能问题,如果要实现一个耗时 CPU 的计算逻辑,处理方法有 2 种:
- 直接在主业务流程中处理;
- 通过网络异步 I/O 给其他进程处理。
目标 : 分别计算从 0 到 1000000000 之间的和
主流程执行
异步网络 I/O
| | —- | —- | —- | | 耗时 | 1.100s | 0.575s |
原因:
异步网络 I/O 充分利用了 Node.js 的异步事件驱动能力,将耗时 CPU 计算逻辑给到其他进程来处理,而无须等待耗时 CPU 计算,可以直接处理其他请求或者其他部分逻辑。第一种同步执行的方式就无法去处理其逻辑,导致性能受到影响。
执行1
const http = require('http');/**** 创建 http 服务,简单返回*/const server = http.createServer((req, res) => {res.write(`${startCount() + nextCount()}`);res.end();});/*** 从 0 计算到 500000000 的和*/function startCount() {let sum = 0;for (let i = 0; i < 500000000; i++) {sum = sum + i;}return sum;}/*** 从 500000000 计算到 1000000000 之间的和*/function nextCount() {let sum = 0;for (let i = 500000000; i < 1000000000; i++) {sum = sum + i;}return sum;}/**** 启动服务*/server.listen(4000, () => {console.log('server start http://127.0.0.1:4000');});
启动服务, 访问http://127.0.0.1:4000
执行2
需要安装, yarn add request-promise
node index.js
// index.jsconst http = require('http');const rp = require('request-promise');/**** 创建 http 服务,简单返回*/const server = http.createServer((req, res) => {Promise.all([startCount(), nextCount()]).then((values) => {let sum = values.reduce(function (prev, curr, idx, arr) {return parseInt(prev) + parseInt(curr);});res.write(`${sum}`);res.end();});});/*** 从 0 计算到 500000000 的和*/async function startCount() {return await rp.get('http://127.0.0.1:4001');}/*** 从 500000000 计算到 1000000000 之间的和*/async function nextCount() {return await rp.get('http://127.0.0.1:4002');}/**** 启动服务*/server.listen(4000, () => {console.log('server start http://127.0.0.1:4000');});
node startServer.js
// startServer.jsconst http = require('http');/**** 创建 http 服务,简单返回*/const server = http.createServer((req, res) => {let sum = 0;for(let i=0; i<500000000; i++){sum = sum + i;}res.write(`${sum}`);res.end();});/**** 启动服务*/server.listen(4001, () => {console.log('server start http://127.0.0.1:4001');});
node nextServer.js
const http = require('http');/**** 创建 http 服务,简单返回*/const server = http.createServer((req, res) => {let sum = 0;for (let i = 500000000; i < 1000000000; i++) {sum = sum + i;}res.write(`${sum}`);res.end();});/**** 启动服务*/server.listen(4002, () => {console.log('server start http://127.0.0.1:4002');});
