zoukankan      html  css  js  c++  java
  • 给 connect 的 static 模块加上url路径前缀

    估计我们使用 connect 都会很自然地按照官方的例子使用静态文件模块 static:

    var connect = require('connect');
    
    connect(
      connect.static(__dirname),
      function (req, res) {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World\n');
      }
    ).listen(8124);
    
    console.log('Server running at http://127.0.0.1:8124/');
    

    基准性能

    为了评测 static 的性能,我们需要又一个基准对比。

    官方最纯洁的 helloworld

    我们使用 nodejs 官方文档给出的 helloworld 做最基础的参照:

    
    ar http = require('http');
    
    http.createServer(function (request, response) {
      response.writeHead(200, {'Content-Type': 'text/plain'});
      response.end('Hello World\n');
    }).listen(8124);
    
    console.log('Server running at http://127.0.0.1:8124/');
    

    最纯洁的 connect helloworld

    不使用任何中间件模块

    
    var connect = require('connect');
    
    connect(function (req, res) {
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end('Hello World\n');
    }).listen(8124);
    
    console.log('Server running at http://127.0.0.1:8124/');
    
    

    结合 domain 模块的 connect helloworld

    
    var connect = require('connect');
    var createDomain = require('domain').create;
    
    connect(
      function (req, res, next) {
        var domain = createDomain();
        domain.on('error', function (err) {
          console.log('errrrrr', err);
          res.statusCode = 500;
          res.end(err.message + '\n');
          domain.dispose();
        });
        domain.run(next);
      },
      function (req, res, next) {
        if (req.url === '/error') {
          process.nextTick(function () {
            res.end('params: ' + req.query.abc);
          });
          return;
        }
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World\n');
      }
    ).listen(8124);
    
    console.log('Server running at http://127.0.0.1:8124/');
    
    

    测试结果

    官方最纯洁的 helloworld: 7851.56 qps

    $ siege -b -c10 -t10S http://127.0.0.1:8124/
    ** SIEGE 2.72
    ** Preparing 10 concurrent users for battle.
    The server is now under siege...
    Lifting the server siege...      done.
    
    Transactions:          78123 hits
    Availability:         100.00 %
    Elapsed time:           9.95 secs
    Data transferred:         0.89 MB
    Response time:            0.00 secs
    Transaction rate:      7851.56 trans/sec
    Throughput:           0.09 MB/sec
    Concurrency:            9.93
    Successful transactions:       78123
    Failed transactions:             0
    Longest transaction:          0.09
    Shortest transaction:         0.00
    

    最纯洁的 connect helloworld: 6808.19 qps

    $ siege -b -c10 -t10S http://127.0.0.1:8124/
    ** SIEGE 2.72
    ** Preparing 10 concurrent users for battle.
    The server is now under siege...
    Lifting the server siege...      done.
    
    Transactions:          78123 hits
    Availability:         100.00 %
    Elapsed time:           9.95 secs
    Data transferred:         0.89 MB
    Response time:            0.00 secs
    Transaction rate:      7851.56 trans/sec
    Throughput:           0.09 MB/sec
    Concurrency:            9.93
    Successful transactions:       78123
    Failed transactions:             0
    Longest transaction:          0.09
    Shortest transaction:         0.00
    

    使用 domain 模块的 connect helloworld: 5601.35 qps

    domain demo for express

    
    $ siege -b -c10 -t10S http://127.0.0.1:8124/
    ** SIEGE 2.72
    ** Preparing 10 concurrent users for battle.
    The server is now under siege...
    Lifting the server siege...      done.
    
    Transactions:          65699 hits
    Availability:         100.00 %
    Elapsed time:           9.65 secs
    Data transferred:         0.75 MB
    Response time:            0.00 secs
    Transaction rate:      6808.19 trans/sec
    Throughput:           0.08 MB/sec
    Concurrency:            9.96
    Successful transactions:       65699
    Failed transactions:             0
    Longest transaction:          0.05
    Shortest transaction:         0.00
    

    带 static 的 connect helloworld: 3636.98 qps

    $ siege -b -c10 -t10S http://127.0.0.1:8124/
    ** SIEGE 2.72
    ** Preparing 10 concurrent users for battle.
    The server is now under siege...
    Lifting the server siege...      done.
    
    Transactions:          34915 hits
    Availability:         100.00 %
    Elapsed time:           9.60 secs
    Data transferred:         0.40 MB
    Response time:            0.00 secs
    Transaction rate:      3636.98 trans/sec
    Throughput:           0.04 MB/sec
    Concurrency:            9.97
    Successful transactions:       34915
    Failed transactions:             0
    Longest transaction:          0.06
    Shortest transaction:         0.00
    

    为什么性能降低了50%

    晕,为什么加上了 static 模块,性能会降低了50%这么多?

    查看 static.send() 源代码:

    // "hidden" file
    if (!hidden && '.' == basename(path)[0]) return next();
    
    fs.stat(path, function(err, stat){
      // mime type
      type = mime.lookup(path);
    
      // ignore ENOENT
      if (err) {
        if (fn) return fn(err);
        return ('ENOENT' == err.code || 'ENAMETOOLONG' == err.code)
          ? next()
          : next(err);
      // redirect directory in case index.html is present
      } else if (stat.isDirectory()) {
        if (!redirect) return next();
        res.statusCode = 301;
        res.setHeader('Location', url.pathname + '/');
        res.end('Redirecting to ' + url.pathname + '/');
        return;
      }
    

    static 模块每次都需要一次文件IO,判断文件是否存在,这是多么损耗性能啊。

    增加静态文件url路径前缀

    既然找到性能问题所在,就可以解决此问题了。对症下药,无需让所有请求都经过 static 处理即可。

    给 static 增加一个url前缀判断,例如 /public/images/logo.jpg 只有前缀是 /public 的 url 请求才需要进入 static 模块处理。

    那么我们改进后的代码应该是这样的:

    
    var connect = require('connect');
    
    var app = connect();
    app.use('/public', connect.static(__dirname));
    
    app.use(function (req, res) {
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end('Hello World\n');
    }).listen(8124);
    
    console.log('Server running at http://127.0.0.1:8124/');
    

    性能如何? wow 6749.03 qps, 几乎和 connect hellowrold 一致。done!

    
    $ siege -b -c10 -t10S http://127.0.0.1:8124/
    ** SIEGE 2.72
    ** Preparing 10 concurrent users for battle.
    The server is now under siege...
    Lifting the server siege...      done.
    
    Transactions:          66073 hits
    Availability:         100.00 %
    Elapsed time:           9.79 secs
    Data transferred:         0.76 MB
    Response time:            0.00 secs
    Transaction rate:      6749.03 trans/sec
    Throughput:           0.08 MB/sec
    Concurrency:            9.97
    Successful transactions:       66073
    Failed transactions:             0
    Longest transaction:          0.03
    Shortest transaction:         0.00
    

    重现一下之前的性能问题,访问 /public/foo 即可重现。

    
    $ siege -b -c10 -t10S http://127.0.0.1:8124/public/foo
    ** SIEGE 2.72
    ** Preparing 10 concurrent users for battle.
    The server is now under siege...
    Lifting the server siege...      done.
    
    Transactions:          37773 hits
    Availability:         100.00 %
    Elapsed time:           9.59 secs
    Data transferred:         0.43 MB
    Response time:            0.00 secs
    Transaction rate:      3938.79 trans/sec
    Throughput:           0.05 MB/sec
    Concurrency:            9.97
    Successful transactions:       37773
    Failed transactions:             0
    Longest transaction:          0.05
    Shortest transaction:         0.00
    
    

    有爱

    记得给 connect.static 加上一个url路径前缀喔!

    ^_^ 希望本文对你有用。

    原贴的链接

  • 相关阅读:
    JavaScript Array 对象方法
    前后台如何转码
    nrm 的使用说明
    sass的学习笔记
    前端书籍概述;
    程序员必读书籍及导读指南
    HTML5之FileReader的使用
    jQery的方法
    jQuery的使用说明
    div,contenteditable编辑器之ctrl+enter换行,enter发送
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/2591139.html
Copyright © 2011-2022 走看看