前阵子研究了当下最火的node.js框架——expressjs的源代码,发现其引入中间件的实现机制很巧妙,但是过多的中间件引入确实对性能影响比较大,虽然expressjs已经很快了,但是我想让他更快一些;再者expressjs的配置可谓复杂,app.set, app.get到底什么时候用什么,学习门槛比较高,我想让他更简单一些;最后expressjs的路由功能代码写的很潇洒,根据request.method分类,app.get, app.post等等,如果要增加一些uri每次都需要修改路由表,对于get和post两种方式的请求得写两遍,我想让他更方便一些。 <br/> <br/> <b>官网地址:<a title=“http://www.rrestjs.com/” href=“http://www.rrestjs.com/”>http://www.rrestjs.com/</a></b> <br/> <br/>rrestjs(ROA-Restful js)是在expressjs代码的基础上开发的(这样可以减少很多bug,同时要感谢expressjs作者visionmedia无私的奉献),不过整个框架结构已经完全改变了,属性以及方法定义也是全新的,可以说是一个全新的node.js框架。先献上一个简单的hello world 的例子吧: <br/><pre>var http = require(‘http’), <br/> rrest = require(‘rrestjs’), <br/> server = http.createServer(rrest(function (req, res) { <br/> res.send(‘hello world’); <br/> })).listen(3000);</pre> <br/>项目及API地址:<a title=“https://github.com/DoubleSpout/rrestjs” href=“https://github.com/DoubleSpout/rrestjs”>https://github.com/DoubleSpout/rrestjs</a> <br/> <br/>A、框架的性能一般看相对于裸奔的node.js性能下降多少,下面先列出大家最关心的性能对比数据: <br/>注:rrestjs和expressjs均未打开session,gzip等影响性能的配置 <br/><pre>测试服务器:cpu(s): Intel® Xeon® E5620 2.4GHZ (8 cpus ) <br/> mem: 6G <br/> system: linux 2.6.8 64bit <br/> node: v-0.6.6 <br/>AB发包服务器:同上 <br/>网络环境:内网 <br/>测试软件:AB <br/> <br/>1、hellow world 输出,1000并发50000个请求 <br/>node:23075 req/sec <br/>expressjs:18452 req/sec <br/>rrestjs:20734 req/sec <br/>*node.js在8核CPU上卓越的性能令人称赞啊 <br/>*这里rrestjs的入口加载机制和更少的入口处理让他比expressjs更快 <br/> <br/>2、小静态index.html输出, 1000并发50000个请求 <br/>node:15471 req/sec <br/>expressjs:9555 req/sec <br/>rrestjs:10411 req/sec <br/>nginx:13550 req/sec <br/>*node在小静态文件处理上本次测试已经和老牌web服务器nginx平分秋色了 <br/>*rrestjs在小静态文件上增加了2级缓存,减少一次I/O操作,所以更快 <br/> <br/>3、jade模版输出,1000并发50000个请求 <br/>expressjs:10609 req/sec <br/>rrestjs:12584 req/sec <br/>rrestjs(jade cache):11772 req/sec <br/>*开启jade的html缓存并不会慢,在5000并发情况下,开启html缓存的性能要更为明显 <br/>*rrestjs还在生成缓存加入了key机制,防止缓存重建时的雪崩效应 <br/>rrestjs减少了很多判断直接调用jade模版接口,所以性能略胜一筹</pre> <br/>完整的AB和webbench测试结果请参阅:<a title=“http://snoopyxdy.blog.163.com/blog/static/6011744020120135424340/” href=“http://snoopyxdy.blog.163.com/blog/static/6011744020120135424340/”>http://snoopyxdy.blog.163.com/blog/static/6011744020120135424340/</a> <br/> <br/>B、代码风格和上手门槛也很重要,expressjs自成一派的代码风格,各种app用顺了其实还是很方便的,但是不够直观,在定义开发模式或生产模式时需要:app.configure(‘production’, function(){});rrestjs则类似nginx那样,只需要修改config.js文件,require不同的config.js文件即可,所有的功能在config.js上都有注释,需要打开,不需要关闭,直观而且简单。例如下面就是配置session的一段config: <br/><pre>isSession:true, //是否开启session,开启会影响性能。 <br/>syncSession:false,//当多进程时是否开启session同步,开启会影响性能。 <br/>sessionName:‘rrSid’, //保存session id 的cookie 的name <br/>sessionExpire:false, //false表示会话session,否则填入100060,表示session有效1分钟 <br/>sessionDbStore:false,//是否使用mongodb数据库存储session,如果设置为true,则不需要同步session</pre> <br/>C、restful是面向资源的架构,rrestjs就是基于这个思想将req.url重新拼装,组成一个uri数组,举个例子:用户访问’/user/face/spout’,则req.path值为[‘user’,‘face’,‘spout’]。只需要去require(‘user’)[‘face’](req, res);这样我们就可以根据用户访问的uri自动处理请求了,当然如果没有找到指定模块,则输出404页面拉。省去了繁琐的url路由,还能自由的配置各种规则,提升了性能,方便了处理。哈哈,不过我承认,取名为roa-restful确实是一个噱头,为了吸引眼球表喷我哦!示例代码: <br/><pre>var http = require(‘http’), <br/> rrest = require(‘rrestjs’), <br/> server = http.createServer(rrest(function (req, res){ <br/> try{//实际测试证明,这里的try语句不会影响整体的性能,放心使用 <br/> require(’./controller/’+req.path[0])[req.path1](req, res);//规则可以自定义,如果访问’/‘则req.pah变为[‘index’,‘index’] <br/> } <br/> catch(err){ <br/> restlog.info(‘Not found module: ‘+err); <br/> res.statusCode = 404; <br/> res.render(’/e404.jade’); <br/> } <br/> })).listen(rrest.config.listenport);</pre> <br/>D、青出于蓝必然胜于蓝,既然在expressjs代码上开发的新框架,必然功能要超越前辈,下面就列出部分expressjs和rrestjs功能对比表(坑爹啊,编辑器没有表格55555) <br/><pre> expressjs node.js <br/>工作环境 √(直接配置) √(加载不同配置文件) <br/>自动Favicon √ √ <br/>IP访问过滤 X √ <br/>自动输出静态文件 √ √ <br/>请求路由 路由表 Restful <br/>Session支持 √(redis支持) √(mongodb支持) <br/>多进程session共享 X √ <br/>请求IP地址 X √ <br/>JSON以及JSONP √ √ <br/>deflat, gzip X √ <br/>模版支持 各种主流 jade <br/>Jade模版html缓存 X √ <br/>日志功能 √ √(支持分级,文件切分) <br/>多进程多任务管理 X √ <br/>子进程自动重启 X √ <br/>压缩合并css或js X √ <br/>自动创建文件夹 X √ <br/>开发模式,文件修改 X √ <br/>自动重启 <br/>数据库连接池封装 X √(mongodb) <br/>自动加载模块 X √(自动加载指定文件夹的模块)</pre> <br/>详细expressjs和rrestjs功能对比表见:<a title=“http://snoopyxdy.blog.163.com/blog/static/60117440201201344425304/” href=“http://snoopyxdy.blog.163.com/blog/static/60117440201201344425304/”>http://snoopyxdy.blog.163.com/blog/static/60117440201201344425304/</a> <br/> <br/>E、最后介绍一下rrestjs内置的ClusterPlus模块 <br/> <br/>node.js 自带的cluster功能很薄弱,只提供基本的几个功能,而ClusterPlus就是为了健壮cluster的,不过在0.7版本的node.js已经大大提升了这项。node.js v-0.70文档API地址:<a title=“http://nodejs.org/docs/v0.7.0/api/index.html” href=“http://nodejs.org/docs/v0.7.0/api/index.html”>http://nodejs.org/docs/v0.7.0/api/index.html</a> <br/> <br/>1、多进程多任务模式,提供了多个node.js进程执行多项任务,看如下代码,表示4个node.js进程监听4个不同端口,并且当其中某一个意外挂掉,主守护进程会自动重启这个进程,还是监听此前挂掉的这个进程的端口。 <br/><pre>module.exports.conf = require(’./config/config’);//说明见github上 <br/> var http = require(‘http’), <br/> rrest = require(‘rrestjs’), <br/> port = [3000, 3001, 3002, 3003], <br/> server = http.createServer(rrest(function (req, res){ <br/> res.send(‘process ‘+rrest.id+’ is listen at ‘+port[rrest.id]+’ : hello world everyone!’); <br/> })); <br/> rrest.listen(server, port);//这里如果不传port参数,则自动去读config.listenPort; </pre> <br/>2、代码修改自动重启,让node.js开发像php那样,放弃频繁的 ctrl+c和↑+enter,之前别人开发的cluster模块也带有reload功能,但是对于新建的文件夹无法监听,而且对于有代码错误会中断程序,ClusterPlus在此基础上重新改写了代码,对于新建文件夹和新建的文件也做到了监听,而且对于有语法错误的修改,会尝试重启然后挂起,直到修改到没有语法错误后才完全重启成功,不会意外中断。示例代码: <br/><pre>module.exports.conf = require(’./config/config’);//说明见github上 <br/> var http = require(‘http’), <br/> rrest = require(‘rrestjs’), <br/> port = [3000, 3001, 3002, 3003], <br/> server = http.createServer(rrest(function (req, res){ <br/> res.send(‘process ‘+rrest.id+’ is listen at ‘+port[rrest.id]+’ : hello world everyone!’); <br/> })).listen(rrest.config.listenPort); </pre> <br/>最后总结一下:用别人的开源框架肯定不是最适合自己项目的,毕竟要被额外绑定很多没用的功能,所以在自己的项目上达到的性能肯定也不是最好的,最好当然是对开源框架做2次开发。其次,无论你代码写的效率如何不高,只要不写死循环,硬件顶上去神马都是浮云。我记得在虚拟机2CPU 2G内存的机子上,node.js跑hello world裸奔撑死跑4000+了,在4CPU,4G内存的老服务器上可以跑到9000+,今天在8CPU上竟然跑到2W3+,硬件才是硬道理啊,优化代码真不如多买几个CPU,多几个G的内存,再装个64位系统足矣,呵呵!
这个是web开发框架还是啥,URL怎么映射啊?
rrestjs是web开发框架,相比expressjs取消了url映射表加快了速度。 例如用户访问 "http://www.cnodejs.org/article/blog" 则直接去配置好的controller目录执行 “require(‘controller/article’)[‘blog’](req, res)”; 快速响应。 如果没有找到相关控制器或方法,则输出404。
纠正一下,是直接在入口处执行 “require(‘controller/article’)‘blog’”;
安装不上,下面是详细信息:
D:\nodejs>npm install rrestjs
npm ERR! Error: Not found: rrestjs@’'
npm ERR! Valid install targets:
npm ERR! [“latest”]
npm ERR! at installTargetsError (D:\nodejs\node_modules\npm\lib\cache.js:410
:10)
npm ERR! at D:\nodejs\node_modules\npm\lib\cache.js:403:17
npm ERR! at saved (D:\nodejs\node_modules\npm\lib\utils\npm-registry-client
get.js:136:7)
npm ERR! at Object.cb [as oncomplete] (D:\nodejs\node_modules\npm\node_modul
es\graceful-fs\graceful-fs.js:36:9)
npm ERR! Report this entire log at:
npm ERR! http://github.com/isaacs/npm/issues
npm ERR! or email it to:
npm ERR! npm-@googlegroups.com
npm ERR!
npm ERR! System Windows_NT 5.1.2600
npm ERR! command “D:\nodejs\\node.exe” “D:\nodejs\node_modules\npm\bin\n
pm-cli.js” “install” "rrestjs"
npm ERR! cwd D:\nodejs
npm ERR! node -v v0.6.1
npm ERR! npm -v 1.0.104
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! D:\nodejs\npm-debug.log
npm not ok
不太明白,那如果我要映射查询参数到URL路径呢?
之前npm一直有点问题,现在已经好了,您可以npm install rrestjs, 如果有问题,可以在 npm update rrestjs 就能保证rrestjs是最新版本了
不明白您的意思,rrestjs是根据您请求的url路径自动加载controller的,rrestjs只是获取get参数封装成key-value对象,至于get参数的判断和获取是controller做的事情,和rrestjs框架无关。 您可以去https://github.com/DoubleSpout/rrestjs查看最新api,有详细说明。
@arden 嗯这个就是restful的思想,我在req.path封装了一个请求的uri路径根据’/'分割的一个数组,可以很方便的取到uri上的内容。你可以看我写的入门教程: http://snoopyxdy.blog.163.com/blog/static/60117440201211743031517/
@snoopy 我觉得只支持jade模版不太好,感觉好多人对jade这种模版用起不习惯,包括我也不习惯。还明ejs, swig来得比较直接~
@arden 今天发布了V0.5版本,把ejs加进去了,呵呵~
安装不起,有问题
byronlee@byronlee:~/wujb$ npm install rrestjs npm http GET https://registry.npmjs.org/rrestjs npm http 304 https://registry.npmjs.org/rrestjs npm ERR! error rolling back Error: EPERM, chmod '/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’ npm ERR! error rolling back rrestjs@0.8.2 { [Error: EPERM, chmod ‘/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’] npm ERR! error rolling back errno: 50, npm ERR! error rolling back code: ‘EPERM’, npm ERR! error rolling back path: ‘/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’ } npm ERR! Error: EPERM, chmod '/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’ npm ERR! { [Error: EPERM, chmod ‘/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’] npm ERR! errno: 50, npm ERR! code: ‘EPERM’, npm ERR! path: ‘/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’ } npm ERR! npm ERR! Please try running this command again as root/Administrator.
npm ERR! System Linux 3.2.0-29-generic npm ERR! command “/usr/local/bin/node” “/usr/local/bin/npm” “install” "rrestjs" npm ERR! cwd /home/byronlee/wujb npm ERR! node -v v0.8.9 npm ERR! npm -v 1.1.61 npm ERR! path /home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin npm ERR! code EPERM npm ERR! errno 50 npm ERR! stack Error: EPERM, chmod '/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’ npm ERR! npm ERR! Additional logging details can be found in: npm ERR! /home/byronlee/wujb/npm-debug.log npm ERR! not ok code 0 byronlee@byronlee:~/wujb$ npm install rrestjs npm http GET https://registry.npmjs.org/rrestjs npm http 304 https://registry.npmjs.org/rrestjs npm ERR! error rolling back Error: EPERM, chmod '/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’ npm ERR! error rolling back rrestjs@0.8.2 { [Error: EPERM, chmod ‘/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’] npm ERR! error rolling back errno: 50, npm ERR! error rolling back code: ‘EPERM’, npm ERR! error rolling back path: ‘/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’ } npm ERR! Error: EPERM, chmod '/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’ npm ERR! { [Error: EPERM, chmod ‘/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’] npm ERR! errno: 50, npm ERR! code: ‘EPERM’, npm ERR! path: ‘/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’ } npm ERR! npm ERR! Please try running this command again as root/Administrator.
npm ERR! System Linux 3.2.0-29-generic npm ERR! command “/usr/local/bin/node” “/usr/local/bin/npm” “install” "rrestjs" npm ERR! cwd /home/byronlee/wujb npm ERR! node -v v0.8.9 npm ERR! npm -v 1.1.61 npm ERR! path /home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin npm ERR! code EPERM npm ERR! errno 50 npm ERR! stack Error: EPERM, chmod '/home/byronlee/node_modules/rrestjs/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin’ npm ERR! npm ERR! Additional logging details can be found in: npm ERR! /home/byronlee/wujb/npm-debug.log npm ERR! not ok code 0
windows下的问题,是依赖模块装不上,你直接从github上打包下载吧
请教 请教始终没弄明白 var RestReq = require(’./RestReq’)(),//封装req RestRes = require(’./RestRes’)(),//封装res bridge = require(’./RestBridge’);
req和res是怎么传递到bridge里面去的
楼主好久没更新啦。
经过测试 好像只支持nodejs0.8的,之后最新的都不知道的,按照步骤操作就会报错的 ,害死我了
snoopy?
@davidzhang 谁叫你挖坟,呵呵 现在用express做rest也不错的吧?
@chapgaga 我只能呵呵了,现在express也还是不错的
@davidzhang 用的最新版?
喂喂喂,你们怎么又挖坟了?!
@chapgaga 对的