精华 高性能,跨平台,轻量级nodejs静态文件ifile模块
发布于 11 年前 作者 DoubleSpout 11862 次浏览 最后一次编辑是 8 年前

之前写了篇博客作为ifile模块的前瞻,终于经过几个晚上的奋斗,ifile模块发布了,ifile模块是nodejs的http/https静态文件模块,主要解决了nodejs对静态文件疲软的支持,模块主要采用libuv的多线程异步编写而成. 整个项目跨平台支持,win8,linux, mac 10.8,均测试通过,mac下挺奇怪的,在线程里加锁会报错,有知道的朋友能指点一二吗?

项目地址:https://github.com/DoubleSpout/ifile 安装方法:

  npm install ifile

ifile模块

代码示例:

  var ifile = require('ifile')
  var http = require('http')
  ifile.add([
   ["/static",__dirname,['js','css','jpg']],
  ],function(req,res,is_static){
      res.statusCode = 404;
      res.end('404')
  })
  var http = require('http');
  http.createServer(function (req, res) {
    ifile.route(req,res);
  }).listen(8124);

下面一张图片用来说明ifile模块和传统nodejs的静态模块的确别和优势:

ifile模块结构图

ifile模块解决了nodejs单一主线程所造成的频繁线程切换的性能损耗,ifile模块所有计算,添加响应头,读取文件,gzip压缩等都是在libuv的工作线程中执行的,所以主线程能够尽可能多的接受用户的请求,增加系统的吞吐量。

下面是一组ifile模块和expressjs框架的静态文件压力测试数据报告,测试机器和网络都相同,test.js为同一个文件,大小是6KB,我们看下测试结果: 首先是expressjs

  express
  ab -c 100 -n 20000 http://192.168.28.5:8126/js/test.js
  Requests per second:    915.21 [#/sec] (mean)
  
  ab -c 500 -n 20000 http://192.168.28.5:8126/js/test.js
  Requests per second:    858.89 [#/sec] (mean)
  
  ab -c 800 -n 20000 http://192.168.28.5:8126/js/test.js
  Requests per second:    668.99 [#/sec] (mean)
  
  ab -c 500 -n 20000 -H "Accept-Encoding: gzip" http://192.168.28.5:8126/js/test.js
  Requests per second:    677.11 [#/sec] (mean)

然后是ifile

  ifile
  ab -c 100 -n 20000 http://192.168.28.5:8125/js/test.js
  Requests per second:    2077.29 [#/sec] (mean)
  
  ab -c 500 -n 20000 http://192.168.28.5:8125/js/test.js
  Requests per second:    1880.00 [#/sec] (mean)
  
  ab -c 800 -n 20000 http://192.168.28.5:8125/js/test.js
  Requests per second:    1791.16 [#/sec] (mean)
  
  ab -c 500 -n 20000 -H "Accept-Encoding: gzip" http://192.168.28.5:8125/js/test.js
  Requests per second:    1858.01 [#/sec] (mean)

在性能上ifile模块比express要高出1倍还不止,有的甚至将近3倍,当然express框架还有其他的一些损耗,比如添加req和res的原形链等等,于是我将express的静态文件功能交由ifile模块来执行,看下测试结果:

  express+ifile
  ab -c 100 -n 20000 http://192.168.28.5:8127/js/test.js
  Requests per second:    1684.85 [#/sec] (mean)
  
  ab -c 500 -n 20000 http://192.168.28.5:8127/js/test.js
  Requests per second:    1717.32 [#/sec] (mean)
  
  ab -c 800 -n 20000 http://192.168.28.5:8127/js/test.js
  Requests per second:    1399.09 [#/sec] (mean)
  
  ab -c 500 -n 20000 -H "Accept-Encoding: gzip" http://192.168.28.5:8127/js/test.js
  Requests per second:    1468.06 [#/sec] (mean)

性能虽较单独使用ifile模块由所下降,但是比expressjs自带的静态文件输出性能提升1倍。 最后我们再看下老牌web服务器nginx的性能把:

  nginx 
  ab -c 100 -n 20000 http://192.168.28.5:8124/js/test.js
  Requests per second:    2634.31 [#/sec] (mean)
  
  ab -c 500 -n 20000 http://192.168.28.5:8124/js/test.js
  Requests per second:    2086.92 [#/sec] (mean)
  
  ab -c 800 -n 20000 http://192.168.28.5:8124/js/test.js
  Requests per second:    2033.45 [#/sec] (mean)
  
  ab -c 500 -n 20000 -H "Accept-Encoding: gzip" http://192.168.28.5:8124/js/test.js
  Requests per second:    2029.59 [#/sec] (mean)

性能相当强悍,比ifile模块还要高一个数量级,看来我写ifile想超越nginx的静态文件性能的愿望是破灭了。 附上ifile整合入expressjs框架的代码:

  var express = require('express');
  var app = express();
  var ifile = require("ifile");
  app.use(ifile.connect()); 
  //default is [['/static',__dirname]];

  app.listen(3000);

最后欢迎广大TX下载试用,有任何问题欢迎留言. 博客原文

ps.社区右下角的markdown简明教程很好,短短几行,让我这个外行人瞬间会编辑markdown了。

11 回复

谢谢分享!

有个地方想请教一下。在图里,你的ifile主线程在实际执行中也是在node.js主线程里吗?

这个用在什么场景下?

@anklos ifile里面处理过程,是调用的libuv帮忙维护的线程池,不是js主线程,所以node.js主线程不会阻塞,等处理完了再回调node.js主线程

@klesh 在node.js应用前面不想部署nginx的时候,提高静态文件效率

我感觉楼主这种做法其实就是 fibjs 的机制。。。 另外,没看出来nginx哪里高了一个数量级? nginx 性能更好,估计是内部使用了文件缓存机制。

@myy

nginx缓存的是fstat,最主要的区别是nginx直接用了sendfile,对小文件而言,省去了两次内存拷贝,直接从文件发送到网卡缓存,这个速度跟node用线程池读比要快很多。

一个数量级可能是笔误,理解意思就行了,静态文件处理,还是nginx给力。

npm install ifle 安装不了这个模块了,求给一个 编译好的可以直接使用的文件模块包,我的邮箱rajan.zhan@foxmail.com

@RajanZhan 大兄弟 你看都没维护了

@NexusLee 好的,我在网上找了源码 ,自己实现了一个

回到顶部