玩转nodeJS类别:使用原生API实现简单利落高效的路由效能(补助nodeJs单机集群),nodeJS本就应有这样轻快

前言:

前言:

nodejs提供了cluster集群(补助端口共享的多进程),cluster基于child_process,process二次封装,方便大家接纳该意义实现单机nodejs的web集群。

拔取nodeJS原生API实现飞速灵活路由,方便与其他库/框架举行整合;

1、cluster的拍卖体制

都了然单线程的nodejs碰到cpu密集型操作会很容易并发CPU满载,服务阻塞的问题;通过类似nginx的master-worker多进程负载处理形式进一步压榨硬件性能,提升nodejs单机服务处理性能。

     m a s t e
r(主进程,分发请求)

        |           |            |        
   |

   worker  worker  worker  worker(子进程,处理请求)

1、原生API,简洁高效的轻轻封装,加速路由解析,nodeJS本就应该如此轻快

2、官方cluster实现

nodejs官方文档中cluster的实现demo:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(8000);
}

2、不含有其他第三方库/框架,可以灵活的烘托任何库/框架举行web开发

3、实现协调的单机nodejs集群,实现多进程端口共享

3.1、代码实现

//开启集群服务
var startClusterSever = function(port, numCPUs) {
    if (cluster.isMaster) {
        for (var i = 0; i < numCPUs; i++) {
            const work = cluster.fork();
            console.log(work.process.pid);
            workers[i] = work;
        }
        cluster.on('exit', (worker, code, signal) => {
            console.log(`worker ${worker.process.pid} died`);
        });
    } else {
        console.log(cluster.worker.id);
        http.createServer((req, res) => {
            console.log("子进程:" + cluster.worker.id + "正在处理请求...");
            routeHandler(req, res);
        }).listen(port);

    }
}

github项目地址:https://github.com/eguid/eguidRouter

3.2、基于eguidRoute路由实现

注:在上一章的eguidRoute基础上平添开启单机集群效应

使用:

eguid.start(8081, 8);//监听8081端口,多线程数量8

const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs');
const cluster = require('cluster');
//路由表
var routeArr = {};
//进程列表
var workers = {};
//进程数量
var clusterNum;
//解析请求地址
var getPathName = function(reqUrl) {
    var urlParse = getUrlParse(reqUrl);
    return urlParse.pathname;
};
//获取url解析
var getUrlParse = function(reqUrl) {
    return url.parse(reqUrl);
};
//是否是一个请求
var isFunc = function(pathName) {
    return typeof routeArr[pathName] === 'function';
};
/**静态资源处理 param(req:请求,res:响应,pathName:路径) */
var resStatic = function(req, res, pathName) {
    fs.readFile(pathName.substr(1), function(err, data) {
        err ? endErrorReq(res, 501) : endStaticReq(res, pathName, data);
        res.end();
    });
};
//响应静态资源
var endStaticReq = function(res, pathName, data) {
    var suffix = path.extname(pathName);
    res.writeHead(200, { 'Content-Type': suffix === ".css" ? 'text/css' : 'text/html;' + 'charset=utf-8' });
    res.write(data);
};
//结束错误请求
var endErrorReq = function(res, err) {
    res.writeHead(err);
    res.end();
};
/** 路由分发处理器 */
var routeHandler = function(req, res) {
    var pathName = getPathName(req.url);
    isFunc(pathName) ? routeArr[pathName](req, res, pathName) : resStatic(req, res, pathName);
    console.log("处理了一个请求:" + pathName);
};
/** 添加动态路由解析  
 * param{
 * reqUrl:请求地址, 
 * service:function(request:请求,response:响应,pathName:请求名)}
 */
var addDynamicRoute = function(reqUrl, service) {
    console.log("添加的服务名:" + reqUrl);
    routeArr[reqUrl] = service;
};
/**  开启服务器并监听端口  param{port:端口号}*/
var startServer = function(port, num) {
    clusterNum = num;
    if (num) {
        startClusterSever(port, num);
    } else {
        //创建服务器  
        http.createServer(function(req, res) {
            routeHandler(req, res);
        }).listen(port); //注意这里的端口改成了变量
        //开启后在控制台显示该服务正在运行  
        console.log('Server running at http://127.0.0.1:' + port);
    }
};
/** 设置静态页面请求别名 param(newUrl:新的请求路径, oldUrl:原始路径) */
var setIndex = function(newUrl, oldUrl) {
    addDynamicRoute(newUrl, function(req, res) {
        resStatic(req, res, oldUrl);
    });
};
/**自定义静态页面处理方式 staticHandlerService=function(req,res,pathName)*/
var setresStaticFunc = function(staticHandlerService) {
    resStatic = staticHandlerService;
};

//开启集群服务
var startClusterSever = function(port, numCPUs) {
    if (cluster.isMaster) {
        for (var i = 0; i < numCPUs; i++) {
            const work = cluster.fork();
            console.log(work.process.pid);
            workers[i] = work;
        }
        cluster.on('exit', (worker, code, signal) => {
            console.log(`worker ${worker.process.pid} died`);
        });
    } else {
        console.log(cluster.worker.id);
        http.createServer((req, res) => {
            console.log("子进程:" + cluster.worker.id + "正在处理请求...");
            routeHandler(req, res);
        }).listen(port);

    }
}
exports.route = routeHandler;
exports.add = addDynamicRoute;
exports.start = startServer;
exports.index = setIndex;
exports.modStatic = setresStaticFunc;
/**
 * eguidRouter快速灵活的路由
 * 功能实现:
 * 1、自动静态路由解析
 * 2、支持手动设置静态路由别名
 * 3、支持创建新的静态路由实现(方便加载模板)
 * 4、动态路由解析
 * 5、自动错误响应
 * 6、使用原生API,无第三方框架
 * 7、支持cluster单机集群(机器性能压榨机)
 */

1、API介绍及利用验证

注:新本子新增一个修改/自定义静态路由处理措施和开启单机集群效益集群

nodejs单机多进程(集群)实现:http://blog.csdn.net/eguid_1/article/details/52849472

1.1、在进口中引入eguidRoute路由模块

var eguid = require(“./eguidRouter”);

1.2、定义一个REST请求处理方法

var getNowTime = function(req, res,
pathName) {
    res.writeHead(200, { ‘Content-Type’:
‘application/json;charset=utf-8’ });
    res.write(“{‘retSt’: 200,’retMsg’: ‘请求成功’,’retData’:’
当前光阴:” + new Date().toLocaleString() + “‘}”);
    res.end();
};

1.3、添加REST请求处理措施到动态路由

add(“请求名”,”请求对应的处理办法”)

例如:

eguid.add(“/getNow提姆e”,
getNowTime);//getNow提姆e请求会自行调用下面定义的getNow提姆(Tim)e方法

如果不欣赏下边这种写法的话,当然也能够这样:

eguid.add(“/getNowTime”,function(req, res,
pathName){…});

1.4、设置静态请求的别名

index(“别名”,”原始静态资源路径”)设置的是静态资源请求的别名

eguid.index(‘/’, ‘/index.html’);//设置首页

eguid.index(‘/helloWorld’,
‘/index.html’);//设置原始页面别名打开,/helloWolrd请求打开的是/index.html静态页面

1.5、创设新的静态路由处理

modStatic(req,res,pathName)

该办法允许更改静态资源访问形式,该方法会覆盖默认的静态路由处理形式,方便从缓存中读取静态资源依然拓展模板操作

1.6、开启服务器,监听端口

eguid.start(8081);

新版帮忙eguid.start(8081,8);//多进程共享端口号8081,开启8个过程,其中含有1个主进程,7个子进程

打开服务器后会自动举行静态资源路由和按照添加的路由举办分析

2、eguid路由0.2.1代码一览,如丝般顺滑的原生API体验 😀

新本子请转到github项目地址查看,github项目地址:https://github.com/eguid/eguidRouter

const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs');
const cluster = require('cluster');
//路由表
var routeArr = {};
//进程列表
var workers = {};
//进程数量
var clusterNum;
//解析请求地址
var getPathName = function(reqUrl) {
    var urlParse = getUrlParse(reqUrl);
    return urlParse.pathname;
};
//获取url解析
var getUrlParse = function(reqUrl) {
    return url.parse(reqUrl);
};
//是否是一个请求
var isFunc = function(pathName) {
    return typeof routeArr[pathName] === 'function';
};
/**静态资源处理 param(req:请求,res:响应,pathName:路径) */
var resStatic = function(req, res, pathName) {
    fs.readFile(pathName.substr(1), function(err, data) {
        err ? endErrorReq(res, 501) : endStaticReq(res, pathName, data);
        res.end();
    });
};
//响应静态资源
var endStaticReq = function(res, pathName, data) {
    var suffix = path.extname(pathName);
    res.writeHead(200, { 'Content-Type': suffix === ".css" ? 'text/css' : 'text/html;' + 'charset=utf-8' });
    res.write(data);
};
//结束错误请求
var endErrorReq = function(res, err) {
    res.writeHead(err);
    res.end();
};
/** 路由分发处理器 */
var routeHandler = function(req, res) {
    var pathName = getPathName(req.url);
    isFunc(pathName) ? routeArr[pathName](req, res, pathName) : resStatic(req, res, pathName);
    console.log("处理了一个请求:" + pathName);
};
/** 添加动态路由解析  
 * param{
 * reqUrl:请求地址, 
 * service:function(request:请求,response:响应,pathName:请求名)}
 */
var addDynamicRoute = function(reqUrl, service) {
    console.log("添加的服务名:" + reqUrl);
    routeArr[reqUrl] = service;
};
/**  开启服务器并监听端口  param{port:端口号}*/
var startServer = function(port, num) {
    clusterNum = num;
    if (num) {
        startClusterSever(port, num);
    } else {
        //创建服务器  
        http.createServer(function(req, res) {
            routeHandler(req, res);
        }).listen(port); //注意这里的端口改成了变量
        //开启后在控制台显示该服务正在运行  
        console.log('Server running at http://127.0.0.1:' + port);
    }
};
/** 设置静态页面请求别名 param(newUrl:新的请求路径, oldUrl:原始路径) */
var setIndex = function(newUrl, oldUrl) {
    addDynamicRoute(newUrl, function(req, res) {
        resStatic(req, res, oldUrl);
    });
};
/**自定义静态页面处理方式 staticHandlerService=function(req,res,pathName)*/
var setresStaticFunc = function(staticHandlerService) {
    resStatic = staticHandlerService;
};

//开启集群服务
var startClusterSever = function(port, numCPUs) {
    if (cluster.isMaster) {
        for (var i = 0; i < numCPUs; i++) {
            const work = cluster.fork();
            console.log(work.process.pid);
            workers[i] = work;
        }
        cluster.on('exit', (worker, code, signal) => {
            console.log(`worker ${worker.process.pid} died`);
        });
    } else {
        console.log(cluster.worker.id);
        http.createServer((req, res) => {
            console.log("子进程:" + cluster.worker.id + "正在处理请求...");
            routeHandler(req, res);
        }).listen(port);

    }
}
exports.route = routeHandler;
exports.add = addDynamicRoute;
exports.start = startServer;
exports.index = setIndex;
exports.modStatic = setresStaticFunc;
/**
 * eguidRouter快速灵活的路由
 * 功能实现:
 * 1、自动静态路由解析
 * 2、支持手动设置静态路由别名
 * 3、支持创建新的静态路由实现(方便加载模板)
 * 4、动态路由解析
 * 5、自动错误响应
 * 6、使用原生API,无第三方框架
 * 7、支持cluster单机集群(机器性能压榨机)
 */

发表评论

电子邮件地址不会被公开。 必填项已用*标注