2

在通过服务器 A 将服务 B 的响应传送到客户端时,我注意到了严重的性能问题。我在调查我们的主要执行代理的节点服务器之一的性能时发现了这个问题。我们正在使用 http-proxy 进行代理,起初我认为是 http-proxy 很慢,但我将问题缩小到那个简单的代码片段,它只是使用 http.get 向另一台服务器发出请求并返回对客户的回应。

服务器 A(代理):

/*jslint node:true nomen:true vars:true*/
var http = require('http');

function outputMs() {
    'use strict';
    var d = new Date();
    var n = d.getUTCMilliseconds();
    return n;
}

http.createServer(function (req, res) {
    'use strict';
    var startTime = outputMs();

    var options = {
        hostname: '10.0.1.114',
        port: 3001,
        path: '/test'
    };

    if (req.url.indexOf('/pipe') > -1) {
        http.get(options, function (proxyRes) {
            // This is slow!!!
            proxyRes.pipe(res);
            proxyRes.on('data', function (chunk) {
                console.log('data:' + (outputMs() - startTime));
                console.log('received:' + chunk);
            });
            proxyRes.on('end', function () {
                console.log('end:' + (outputMs() - startTime));
            });
        });
    } else {
        var data;
        http.get(options, function (proxyRes) {
            // This is fast!!!
            proxyRes.on('data', function (chunk) {
                console.log('data:' + (outputMs() - startTime));
                data += chunk;
            });
            proxyRes.on('end', function () {
                console.log('end:' + (outputMs() - startTime));
                res.end(data);
            });
        });
    }
}).listen(3000);

服务器 B:

/*jslint node:true nomen:true vars:true*/
var http = require('http');

http.createServer(function (req, res) {
    'use strict';
    res.end('Hello World');
}).listen(3001);

在这两种情况下,请求事件似乎都需要相同的时间,但客户端接收响应的速度要慢得多。使用 curl 进行测试:

使用管道:

C:\github\mecs> curl -s -w "%{time_total}\n" -o /dev/null http://54.209.35.253:3000/pipe
0.265
C:\github\mecs> curl -s -w "%{time_total}\n" -o /dev/null http://54.209.35.253:3000/pipe
0.265

不使用管道:

C:\github\mecs> curl -s -w "%{time_total}\n" -o /dev/null http://54.209.35.253:3000
0.047
C:\github\mecs> curl -s -w "%{time_total}\n" -o /dev/null http://54.209.35.253:3000
0.063

两台服务器都在 AWS 上的微实例上运行,运行 Ubuntu Server 12.04.1 LTS 和 node.js 0.10.21。我在节点 0.10.20 和 0.8.24 以及 Ubuntu Server 12.04.2 和 13.10 上重现了该问题。在 Windows 上未观察到该问题。

有没有人遇到同样的问题?有什么解决办法吗?

非常感谢你的帮助...

4

2 回答 2

5

您可能需要执行类似 socket.setNoDelay([noDelay]) 的操作。不知道如何使用 http 模块做到这一点。我的猜测是一端正在等待套接字关闭,因为它是一条小消息,当它超时时,您会看到响应。

setNoDelay() 必须在客户端请求上调用,我第一次尝试它是在我的代理请求上。

server.on('connection', function (socket) {
    '使用严格';
    console.log('server.on.connection - setNoDelay');
    socket.setNoDelay(true);
});
于 2013-11-08T16:26:03.093 回答
0

我有类似的错误。在我使用keepAlive=true 的代理在请求选项中设置代理后,我能够更快地获得响应。

于 2015-03-20T05:18:58.753 回答