在AWS上运行的Node.js性能下降

时间:2013-12-09 20:33:57

标签: node.js amazon-web-services express amazon-ec2

我使用Node.js在AWS上运行一个非常简单的RESTful API。 API以'/ rest / users / jdoe'的形式接受请求并返回以下内容(它全部在内存中完成,不涉及数据库):

{
    username: 'jdoe',
    firstName: 'John',
    lastName: 'Doe'
}

与本地网络相比,此API在Node.js + AWS上的性能非常糟糕 - 本地网络上仅有9个请求/秒,而2,214个请求/秒。 AWS正在运行m1.medium实例,而本地节点服务器是具有Intel i7-950处理器的台式机。试图弄清楚为什么会有如此巨大的性能差异。

使用Apache Bench的基准测试如下:

本地网络

10,000个并发为100 / group的请求

> ab -n 10000 -c 100 http://192.168.1.100:8080/rest/users/jdoe

Document Path:          /rest/users/jdoe
Document Length:        70 bytes

Concurrency Level:      100
Time taken for tests:   4.516 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      2350000 bytes
HTML transferred:       700000 bytes
Requests per second:    2214.22 [#/sec] (mean)
Time per request:       45.163 [ms] (mean)
Time per request:       0.452 [ms] (mean, across all concurrent requests)
Transfer rate:          508.15 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.4      0       2
Processing:    28   45   7.2     44      74
Waiting:       22   43   7.5     42      74
Total:         28   45   7.2     44      74

Percentage of the requests served within a certain time (ms)
  50%     44
  66%     46
  75%     49
  80%     51
  90%     54
  95%     59
  98%     65
  99%     67
 100%     74 (longest request)

AWS

1,000个并发为100 / group的请求 (10,000个请求可能需要太长时间)

C:\apps\apache-2.2.21\bin>ab -n 1000 -c 100 http://54.200.x.xxx:8080/rest/users/jdoe
Document Path:          /rest/users/jdoe
Document Length:        70 bytes

Concurrency Level:      100
Time taken for tests:   105.693 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      235000 bytes
HTML transferred:       70000 bytes
Requests per second:    9.46 [#/sec] (mean)
Time per request:       10569.305 [ms] (mean)
Time per request:       105.693 [ms] (mean, across all concurrent requests)
Transfer rate:          2.17 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       98  105   3.8    106     122
Processing:   103 9934 1844.8  10434   10633
Waiting:      103 5252 3026.5   5253   10606
Total:        204 10040 1844.9  10540   10736

Percentage of the requests served within a certain time (ms)
  50%  10540
  66%  10564
  75%  10588
  80%  10596
  90%  10659
  95%  10691
  98%  10710
  99%  10726
 100%  10736 (longest request)

问题:

  • AWS的连接时间为105毫秒(平均),而本地网络为0毫秒。我认为这是因为它需要花费更多的时间来打开AWS的套接字然后再打开本地网络上的服务器。假设有来自全球多台机器的请求,那么在这里可以做些什么来提高负载下的性能。
  • 服务器处理时间更严重 - 本地服务器为45毫秒,而AWS为9.9秒!我无法弄清楚这里发生了什么。服务器只按9.46请求/秒。这是花生!

对这些问题的任何见解都非常感谢。如果在这样一个简单的应用程序上无法快速执行,那么我很担心在Node + AWS上安装一个认真的应用程序。

这里的参考是我的服务器代码:

var express = require('express');

var app = express();

app.get('/rest/users/:id', function(req, res) {
    var user = {
        username: req.params.id,
        firstName: 'John',
        lastName: 'Doe'
    };
    res.json(user);
});

app.listen(8080);
console.log('Listening on port 8080');

修改

单独发送的请求(-n 1 -c 1)

Requests per second:    4.67 [#/sec] (mean)
Time per request:       214.013 [ms] (mean)
Time per request:       214.013 [ms] (mean, across all concurrent requests)
Transfer rate:          1.07 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      104  104   0.0    104     104
Processing:   110  110   0.0    110     110
Waiting:      110  110   0.0    110     110
Total:        214  214   0.0    214     214

10请求同时发送(-n 10 -c 10)

Requests per second:    8.81 [#/sec] (mean)
Time per request:       1135.066 [ms] (mean)
Time per request:       113.507 [ms] (mean, across all concurrent requests)
Transfer rate:          2.02 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       98  103   3.4    102     110
Processing:   102  477 296.0    520     928
Waiting:      102  477 295.9    520     928
Total:        205  580 295.6    621    1033

使用wrk的结果

如安德烈西多罗夫所说。结果好多了 - 每秒2821个请求:

Running 30s test @ http://54.200.x.xxx:8080/rest/users/jdoe
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   137.04ms   48.12ms   2.66s    98.89%
    Req/Sec   238.11     27.97   303.00     88.91%
  84659 requests in 30.01s, 19.38MB read
  Socket errors: connect 0, read 0, write 0, timeout 53
Requests/sec:   2821.41
Transfer/sec:    661.27KB

所以看起来肯定是ApacheBench的罪魁祸首!令人难以置信!

1 个答案:

答案 0 :(得分:7)

这可能是ab问题(另见this question)。您的服务器代码没有任何问题。我建议尝试使用wrk负载测试工具进行基准测试。你在我的t1.micro上的例子:

wrk git:master ❯ ./wrk -t12 -c400 -d30s http://some-amazon-hostname.com/rest/users/10                                                                                                                                                                                          ✭
Running 30s test @ http://some-amazon-hostname.com/rest/users/10
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   333.42ms  322.01ms   3.20s    91.33%
    Req/Sec   135.02     59.20   283.00     65.32%
  48965 requests in 30.00s, 11.95MB read
Requests/sec:   1631.98
Transfer/sec:    407.99KB