Nodejs反向代理性能

9
我正在调查使用Node作为反向代理的可能性。我的项目的主要目标之一是实现非常高的性能。因此,我已经设置了一个Node服务器来代理请求到目标Node服务器,无论请求是什么,它都会响应“hello world”。
使用Apache Bench,我对每秒处理的请求数进行了比较。代理、目标和调用方分别在AWS的三个独立M1大型实例上。我的结果令人沮丧和困惑。
直接从调用方到目标:
ab -c 100 -n 10000 http://target-instance/

=每秒约2600个请求

从调用者通过代理到目标端

ab -c 100 -n 10000 http://proxy-instance/

每秒处理约1100个请求。

使用lighttpd,我能够在代理和目标服务器上获得大约3500个请求/秒。

我感到失望的是代理服务器的表现不如目标服务器。当比较其他产品(如lighttpd)时,我曾经看过代理与目标服务器达到了相当的结果,所以我对Node为什么不能达到同样的结果感到困惑。

这是我在Node v0.5.9中的代理代码:有什么我遗漏的吗?

var server =
http.createServer(function(req, res){
    var opts = { host: 'target-instance',
                 port: 80,
                 path: '/',
                 method: 'GET'};
    var proxyRequest = http.get(opts, function(response){
            response.on('data', function(chunk){
                    res.write(chunk);
            });
            response.on('end', function(){
                    res.end()
            });
    });
});
server.listen(80);

为什么我认为我需要什么?我正在研究构建代理产品,并尝试选择最佳的基础技术。 - jonnysamps
4个回答

8
虽然Node.js非常高效,但它不支持多线程,因此代理节点将处理比目标节点更多的连接,但只有一个线程,因此会成为瓶颈。有两种解决方法:
  1. 在多个节点代理实例(例如nginx)前使用多线程负载均衡器。
  2. 更改您的节点代理以使用多进程。有多个可用于此的节点模块,但现在Node已经包含“cluster”,并且对我来说似乎是最简单的方法。

2

不了解性能,这是真的吗?API使用起来非常简单,以至于我认为它是代理的“天真方法”。 - Camilo Martin

0
从http.request文档中:
发送“Connection:keep-alive”将通知Node应该保持与服务器的连接,直到下一次请求。
所以我打赌你的代理每个请求都在重新连接目标实例,这非常低效。我认为你的options变量应该像这样加快速度:
var opts  {
    host: 'target-instance',
    port: 80,
    path: '/',
    headers: {
        "Connection": "keep-alive"
    }
};

这似乎没有帮助。Node文档还提到默认使用Connection: keep-alive。事实上,如果不将其添加到opts中,我会获得更好的性能。 - jonnysamps

0

在添加连接:keep-alive头之后,您还应该使用keep-alive(-k选项)进行测试:

ab -c 100 -n 10000 -k http://xxxx/


这样可以大大加快直接发送到目标的请求数量,每秒可达6k,但对于通过代理的请求没有帮助。 - jonnysamps

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接