高性能http/https的Nodejs路由模块iroute

高性能http/https的Nodejs路由模块iroute

一直想写一个高性能的路由模块,原来rrestjs框架那种try{}catch(){}方式感觉太丑陋了,最近有幸写了一个简单、轻量、高效的iroute路由模块。

irtoue具体功能可以根据http的请求方法归类路由,根据请求地址和url参数路由到不同的action中去,目前支持,get,post,put、delete、options、head这6种,其他http的method都归于other。

不同于普通的正则匹配,iroute模块采用c++的字符串验证,速度更快,跨平台支持,windows, linux和mac都经过了测试。

适用人群:不想用expressjs框架,只想用一个简单的路由给自己的应用或者站点,或者对性能要求比较高的用户。

安装方法: npm install iroute 或者直接去github上下载源码然后执行 node-gyp rebuild github地址:https://github.com/DoubleSpout/iroute

1、iroute模块的性能和传统正则匹配对比: A、注册100个路由,进行匹配1000次

regexp: 11ms
cb1 run times :1000
iroute: 3ms
cb2 run times :1000

B、注册1000个路由,进行匹配10000次

regexp: 1107ms
cb1 run times :10000
iroute: 251ms
cb2 run times :10000

iroute模块在普通2cpu的linux机器上性能差不多是原生的js正则的4倍。

2、iroute模块的api iroute模块api很简单,只有2个,1个用作注册路由规则,另外一个负责路由匹配。 A、iroute.add(routearray [,not_match_function]); 一个简单的代码示例,很容易就看明白了:

var iroute = require("iroute");"
iroute.add([
["get:/test1/",function(req,res){res.end('test1')}],
["get:/test2/test2/test2/test2/",function(req,res){res.end('test2')}],
["get:/test3/test3/test3/test3?key1&key2&key3",function(req,res){res.end('test3')}],
["post:/test4",function(req,res){res.end('test4')}],
["post:/test5/test5/test5/test5",function(req,res){res.end('test5')}],
["post:/test6/test6/test6/test6?key1&key2&key3",function(req,res){res.end('test6')}],
["put:/test7",function(req,res){res.end('test7')}],
["put:/test8/test8/test8/test8",function(req,res){res.end('test8')}],
["put:/test9/test9/test9/test9?key1",function(req,res){res.end('test9')}],
["delete:/test10",function(req,res){res.end('test10')}],
["delete:/test11/test11/test11/test11",function(req,res){res.end('test11')}],
["delete:/test12/test12/test12/test12?key1&key2&key3&key4&key5&key6&key7&key8&key9&key10",function(req,res){res.end('test12')}],
["head:/test6/test6/test6/test6?key1&key2&key3",function(req,res){res.end('')}],
["options:/test6/test6/test6/test6?key1&key2&key3",function(req,res){res.end('test14')}],
["other:/test6/test6/test6/test6?key1&key2&key3",function(req,res){res.end('test15')}],
],function(req,res){
  res.statusCode = 404;
	res.end('404')
})

not_match_function接受2个参数,req和res,当所有路由匹配不成功会调用这个函数

B、iroute.route(req,res); 这个方法用来进行路由匹配,放在入口处即可,比如下面这个代码就是一个简单的应用

var http = require('http');
http.createServer(function (req, res) {    
  	var buf_list = [];
  	var len=0;
  	req.on("data",function(chunk){
  		buf_list.push(chunk);
  		len += chunk.length;
  	})
  	req.on("end", function(){
  		req.body = Buffer.concat(buf_list, len).toString();
  		if(req.url != '/favicon.ico') {
	 iroute.route(req,res);
	} 
})

}).listen(8124);

欢迎广大node爱好者试用~ 最后附上expressjs使用简单代码:

    var express = require('express');
    var app = express();
    var iroute = require("iroute");
  
    var route_array = [
      ["get:/hello/world",function(req,res){res.end('hello world')}],
    ]
  
    app.use(iroute.connect(route_array));
  
    app.listen(3000);

这样在浏览器输入/hello/world就可以看到 hello world,输入其他路劲则是404

博客原文

另外为什么把代码加粗什么的功能键去掉了?不会排版了。。。


14 回复

高性能http/https的Nodejs路由模块iroute

我一直想写一个高性能的路由模块,原来rrestjs框架那种try{}catch(){}方式感觉太丑陋了,最近有幸写了一个简单、轻量、高效的iroute路由模块。

iroute模块的具体功能

iroute模块可以根据HTTP的请求方法(如GET、POST、PUT、DELETE、OPTIONS、HEAD)归类路由,并根据请求地址和URL参数路由到不同的action中。目前支持以下六种HTTP方法:getpostputdeleteoptionshead。其他HTTP方法均归类为other

性能优势

与传统的正则表达式匹配相比,iroute模块采用了C++的字符串验证技术,从而实现了更快的速度。该模块在Windows、Linux和Mac平台上都进行了充分的测试,确保了跨平台的支持性。

适用人群

iroute模块适用于那些希望使用一个简单的路由来构建应用或网站,而不愿意引入复杂的Express框架,或者对性能有较高要求的用户。

安装方法

可以通过npm安装iroute模块:

npm install iroute

也可以从GitHub上下载源码并执行:

node-gyp rebuild

GitHub地址:iroute

性能对比

以下是iroute模块与传统正则表达式匹配的性能对比:

  • 注册100个路由,进行匹配1000次:

    • 正则表达式:11毫秒
    • iroute:3毫秒
  • 注册1000个路由,进行匹配10000次:

    • 正则表达式:1107毫秒
    • iroute:251毫秒

在普通双核Linux机器上,iroute模块的性能大约是原生JavaScript正则表达式的4倍。

API介绍

iroute模块API非常简单,仅包含两个主要方法:一个用于注册路由规则,另一个用于进行路由匹配。

1. 注册路由规则
var iroute = require("iroute");

iroute.add([
  ["get:/test1/", function(req, res) { res.end('test1'); }],
  ["get:/test2/test2/test2/test2/", function(req, res) { res.end('test2'); }],
  ["post:/test4", function(req, res) { res.end('test4'); }],
  // 更多路由规则...
], function(req, res) {
  res.statusCode = 404;
  res.end('404');
});

not_match_function接受两个参数reqres,当所有路由匹配不成功时会调用这个函数。

2. 路由匹配
var http = require('http');

http.createServer(function (req, res) {
  var buf_list = [];
  var len = 0;

  req.on("data", function(chunk) {
    buf_list.push(chunk);
    len += chunk.length;
  });

  req.on("end", function() {
    req.body = Buffer.concat(buf_list, len).toString();

    if (req.url !== '/favicon.ico') {
      iroute.route(req, res);
    }
  });
}).listen(8124);

示例代码

这里是一个使用Express集成iroute模块的简单示例:

var express = require('express');
var app = express();
var iroute = require("iroute");

var route_array = [
  ["get:/hello/world", function(req, res) { res.end('hello world'); }],
];

app.use(iroute.connect(route_array));

app.listen(3000);

在浏览器中访问/hello/world可以显示“hello world”,而其他路径则返回404错误。

结语

欢迎广大Node爱好者试用iroute模块!希望这个模块能够帮助你构建更高效的应用程序。


不知道是否可以跟 connection 结合使用

目前没封装~

对于静态资源呢?

NB,顶!

这个只是对请求路由的封装,没有做静态资源的控制

哈,昨天就在github上看到你这个模块了,是研究libuv的成果?

哈哈,我也奇怪,我还在调试发布的时候怎么又人watch了,一看头像就是你了,哈哈~ 没用libuv,多线程有时不一定有单线程高效,而且还要处理各种锁。

大大.能+Q问题儿童么

hoho~是我写的一个bug,忘记考虑直接请求’/'这种情况了,已经fixed了,谢谢你的测试啊,你可以npm install iroute新版本0.2.4,试试~

53822985

大型项目要一个请求一个请求的写在这个文件中,不可以通过中间件加载一类型请求到一条记录中去吗 例如: 订单类: /order/add;/order/delete;order/update;order/pay; app.use('/order') //如果能这样把某一类请求放在一个模块中,加载进来不更方便? \n

路由是分散在每个action文件中好呢,还是集中一起在配置文件中好呢?

iroute 模块是一个高性能的 Node.js 路由模块,适用于希望使用简单且快速路由机制的应用或站点。与传统的正则表达式路由相比,iroute 使用 C++ 的字符串验证技术,显著提升了路由处理的速度,并且具有跨平台兼容性(Windows、Linux 和 macOS)。

示例代码

安装 iroute 模块

首先,通过 npm 安装 iroute

npm install iroute

基本用法

// 引入 http 模块
const http = require('http');

// 引入 iroute 模块
const iroute = require('iroute');

// 定义路由规则
iroute.add([
  // GET 请求路由
  ["get:/test1/", (req, res) => res.end('test1')],
  ["get:/test2/test2/test2/test2/", (req, res) => res.end('test2')],
  // POST 请求路由
  ["post:/test4", (req, res) => res.end('test4')],
  // PUT 请求路由
  ["put:/test7", (req, res) => res.end('test7')],
  // 其他请求类型
  ["delete:/test10", (req, res) => res.end('test10')],
  // 未匹配到任何路由时的默认处理函数
  function(req, res) {
    res.statusCode = 404;
    res.end('404');
  }
]);

// 创建 HTTP 服务器
http.createServer((req, res) => {
  // 处理请求体
  let chunks = [];
  req.on('data', (chunk) => chunks.push(chunk));
  req.on('end', () => {
    req.body = Buffer.concat(chunks).toString();
    if (req.url !== '/favicon.ico') {
      // 进行路由匹配
      iroute.route(req, res);
    }
  });
}).listen(8124, () => console.log('Server listening on port 8124'));

解释

  • iroute.add() 方法用于添加路由规则,支持多种 HTTP 方法(如 GET, POST, PUT 等),并可以在未匹配到任何路由时指定一个默认的处理函数。
  • iroute.route() 方法用于实际的路由匹配过程,它接受请求对象 (req) 和响应对象 (res) 作为参数,并根据请求的方法和 URL 分发到相应的处理函数。

通过这种方式,iroute 模块提供了一种高效且简洁的方式来管理 HTTP 请求的路由逻辑。

回到顶部