为什么在Nginx中增加worker_connections会使node.js集群中的应用程序变慢?

时间:2016-02-17 02:44:09

标签: javascript node.js performance nginx gatling

我正在将我的应用程序转换为node.js集群,我希望它可以提高我的应用程序的性能。

目前,我正在将应用程序部署到2个EC2 t2.medium实例。我有Nginx作为代理和ELB。

这是我的快速集群应用程序,它是文档中非常标准的。

var bodyParser = require('body-parser');
var cors = require('cors');
var cluster = require('cluster');
var debug = require('debug')('expressapp');

if(cluster.isMaster) {
  var numWorkers = require('os').cpus().length;
  debug('Master cluster setting up ' + numWorkers + ' workers');

  for(var i = 0; i < numWorkers; i++) {
    cluster.fork();
  }

  cluster.on('online', function(worker) {
    debug('Worker ' + worker.process.pid + ' is online');
  });

  cluster.on('exit', function(worker, code, signal) {
    debug('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
    debug('Starting a new worker');
    cluster.fork();  
  });
} else {
  // Express stuff
}

这是我的Nginx配置。

nginx::worker_processes: "%{::processorcount}"
nginx::worker_connections: '1024'
nginx::keepalive_timeout: '65'

我在Nginx服务器上有2个CPU。

这是我之前的表现。

enter image description here

我得到1,500个请求/ s,这是非常好的。现在我想我会增加Nginx上的连接数,这样我就可以接受更多的请求了。我这样做。

nginx::worker_processes: "%{::processorcount}"
nginx::worker_connections: '2048'
nginx::keepalive_timeout: '65'

这是我演出后的表现。

enter image description here

我觉得它比以前更糟糕。

我使用gatling进行性能测试,这是代码。

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._

class LoadTestSparrowCapture extends Simulation {
  val httpConf = http
    .baseURL("http://ELB")
    .acceptHeader("application/json")
    .doNotTrackHeader("1")
    .acceptLanguageHeader("en-US,en;q=0.5")
    .acceptEncodingHeader("gzip, defalt")
    .userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0")

    val headers_10 = Map("Content-Type" -> "application/json")

    val scn = scenario("Load Test")
      .exec(http("request_1")
        .get("/track"))

    setUp(
      scn.inject(
        atOnceUsers(15000)
      ).protocols(httpConf))
}

我将它部署到了我的gatling集群。所以,我有3个EC2实例在30秒内向我的应用程序发出15,000个请求。

问题是,我有什么办法可以提高我的应用程序性能,或者我只需要添加更多的机器?

我测试的路线非常简单,我收到请求并将其发送到RabbitMQ,以便进一步处理。所以,那条路线的反应非常快。

1 个答案:

答案 0 :(得分:1)

您已经提到过您正在使用AWS并在ELB中的EC2实例前面。我看到你得到502和503状态代码。这些可以从ELB或您的EC2实例发送。确保在进行负载测试时,您知道错误来自何处。您可以在ELB CloudWatch metrics的AWS控制台中进行检查。

基本上HTTPCode_ELB_5XX表示您的ELB发送了50倍。另一方面,HTTPCode_Backend_5XX发送了50x。您还可以在ELB的日志中验证。您可以找到更好的ELB错误解释here

要在AWS上进行加载测试,您一定要阅读this。重点是ELB只是另一组机器,如果负载增加需要扩展。默认缩放策略是(引自&#34; Ramping Up Testing&#34;)部分:

  

准备好测试工具后,您需要定义负载的增长。我们建议您每五分钟以不超过50%的速度增加负载。

这意味着当您从一些并发用户开始时,假设1000,默认情况下,您应该在5分钟内最多增加1500。这将保证ELB随着服务器的负载而扩展。确切的数字可能会有所不同,您必须自己测试它们。上次我测试了它的持续负载为1200 req./s w / o一个问题,然后我开始接收50x。您可以从单个客户端轻松地从X到Y用户运行加速场景并等待50x。

下一个非常重要的事情(来自部分&#34; DNS Resoultion&#34;)是:

  

如果客户端每分钟至少重新解析一次DNS,则客户端将不会使用Elastic Load Balancing添加到DNS的新资源。

简而言之,这意味着您必须保证DNS中的TTL得到尊重,或者您的客户端通过执行DNS查找来重新解析并轮换他们收到的DNS IP,以保证循环方式以分配负载。如果不是(例如仅从一个客户端进行测试,而不是您的情况),您可以通过将所有流量仅定位到一个实例来重载一个ELB实例来扭曲结果。这意味着ELB根本不会扩展。

希望它会有所帮助。