文件较小的 node.js HTTP 服务器中的响应速度要慢得多

gre*_*uze 5 performance http node.js

我正在为 node.js 中的简单 HTTP 服务器开发性能测试:

var http = require('http');
var fs = require('fs');

var NO_CACHE = true;
var fileCache;
var sendFile = function(conn, file) {
    conn.writeHead(200, {'Content-Type': 'text/html', 'Content-Length': file.length});
    conn.write(file);
    conn.end();
}
http.createServer(function (req, res) {
    if (NO_CACHE || fileCache == undefined) {
        fs.readFile('index.html', function(err, file) {
        fileCache = file;
        sendFile(res, fileCache);
        });
    } else {
        sendFile(res, fileCache);
    }
}).listen(8080, 'localhost');
Run Code Online (Sandbox Code Playgroud)

(代码也可以在这里找到)。

服务器总是读取文件“index.html”并返回它。我意识到如果文件大于或等于 65483 字节(非常接近 2^16 但不准确),服务器会在 1-3 毫秒内给出结果,如果文件更小,它会持续 38-40 毫秒到给出响应(可以在此处找到恰好 65483 字节的 index.html 文件)。响应中的标头大约为 128 个字节:

Content-Type: text/html
Content-Length: 65483
Date: Thu, 14 May 2015 13:58:21 GMT
Connection: keep-alive
Run Code Online (Sandbox Code Playgroud)

前两个头由服务器设置,后两个由任何中间件自动设置。文件大小加上前两个标题是 65533 字节,非常接近 65535 (2^16 - 1),差异可能是因为这两个标题中的回车。

这种行为对我来说看起来很奇怪,因为更大的文件应该持续更多的读取时间,并且时间差异非常大。

我使用了 node.js 0.10.38 和 0.12.2,结果相同。对于性能测试,我使用了 jMeter 2.13。

作为记录,在 jMeter 中使用具有相同文件和相同测试计划的 vert.x 不会发生这种行为(使用 vert.x 服务器,读取更大的文件需要更多时间)。

如果有人知道原因可能是什么(以及如何避免小文件的原因),我很想知道。

gre*_*uze 4

正如bayou.io指出的,该行为是由 TCP noDelay 引起的。我添加到服务器:

server.on("connection", function (socket) {
    socket.setNoDelay(true);
});
Run Code Online (Sandbox Code Playgroud)

并且它按照预期在 1-3 毫秒内给出响应。

  • 我认为文档的意思是“true”是方法参数的默认值 - 不带参数的“setNoDelay()”与“setNoDelay(true)”相同。该选项的默认值仍然是“false” (2认同)