使用Node和Heroku加载平衡

时间:2015-07-07 03:21:05

标签: node.js heroku load-balancing

我有一个网络应用程序,接受来自ios应用程序的api请求。我的网络应用程序使用他们的免费dyno托管在Heroku上,每个请求可以处理512 MB的数据。因为节点是单线程应用程序,所以一旦我们开始从ios端到Web服务器获得更高级别的流量,这将是一个问题。我也不是世界上最富有的人,所以我想知道创建另一个免费的heroku应用程序并使用循环方法来平衡从ios应用程序收到的负载是否聪明?

我只需要指出正确的方向。垂直扩展在财务上不是一个真正的选择。

4 个答案:

答案 0 :(得分:6)

我是Heroku的Node.js平台所有者。

您可能正在进行一些过早优化。 Node.js是我们最小的1X大小(512MB RAM),可以处理数百个同时连接和每分钟数千个请求。

如果您的iOS应用始终如一,那么可能需要考虑获利!

答案 1 :(得分:3)

正如丹尼尔所提到的,它反对Heroku规则。说过可能有其他服务可以让你这样做。 解决此问题的一种方法是使用带有ZeroMQ的群集模块(在使用模块之前需要安装ZeroMQ - 请参阅module description)。

var cluster = require('cluster');
var zmq = require('zmq');

var ROUTER_SOCKET = 'tcp://127.0.0.1:5555';
var DEALER_SOCKET = 'tcp://127.0.0.1:7777';

if (cluster.isMaster) {
  // this is the main process - create Router and Dealer sockets
  var router = zmq.socket('router').bind(ROUTER_SOCKET);
  var dealer = zmq.socket('dealer').bind(DEALER_SOCKET);

  // forward messages between router and dealer
  router.on('message', function() {
    var frames = Array.prototype.slice.cal(arguments);
    dealer.send(frames);
  });

  dealer.on('message', function() {
    var frames = Array.prototype.slice.cal(arguments);
    router.send(frames);
  });

  // listen for workers processes to come online
  cluster.on('online', function() {
    // do something with a new worker, maybe keep an array of workers
  });

  // fork worker processes
  for (var i = 0, i < 100; i++) {
    cluster.fork();
  }
} else {
  // worker process - connect to Dealer
  let responder = zmq.socket('rep').connect(DEALER_SOCKET);

  responder.on('message', function(data) {
    // do something with incomming data
  })
}

这只是为了指出你正确的方向。如果你考虑一下,你可以创建一个带有参数的脚本,该脚本将告诉它是主进程还是工作进程。然后在主服务器上按原样运行它,并在其他服务器上使用worker标志运行它,这将强制它连接到主经销商。

现在您的主应用程序需要将请求发送到路由器,稍后将转发给工作进程:

var zmq = require('zmq');
var requester = zmq.socket('req');

var ROUTER_SOCKET = 'tcp://127.0.0.1:5555';

// handle replies - for example completion status from the worker processes
requester.on('message', function(data) {
  // do something with the replay
});

requester.connect(ROUTER_SOCKET);

// send requests to the router
requester.send({
  // some object describing the task
});

答案 2 :(得分:2)

首先,正如其他回复所指出的,运行两个应用程序副本以避免Heroku的限制违反了他们的ToS,这可能不是一个好主意。

然而,有一些好消息。对于初学者(来自Heroku's docs):

  

dyno管理器将重新启动你的d​​yno并记录一个R15错误,如果内存使用a:

     
      
  • 免费,爱好或标准-1x dyno达到2.5GB,是配额的五倍。
  •   

据我所知,尽管你的dyno拥有512mb的实际 RAM,但它会在实际重启之前换出5倍。所以你可以超过512mb(只要你愿意支付交换到磁盘的性能损失,这可能很严重)。

除此之外,Heroku还可以通过第二种方式进行收费,并允许您根据需要上下调整您的dyno形成。通过点击Heroku API在你自己的应用程序中这很容易做到 - 我看到你用NodeJS标记了这个,所以你可能想看看:

这两个模块都允许你放大和缩小dynos的形成 - 使用简单的启发式(比如,总是有一个备用的1X dyno运行),你可以在处理请求时增加容量,并摆脱它api请求未运行时的备用容量。鉴于你被第二个计费,这最终会变得非常便宜; 1X dynos可以运行到5¢小时。如果你最终每天运行额外的dynos几个小时,对你来说这是一个非常非常小的成本。

最后:还有第三方服务,例如AdeptHirefire(来自Google的两个随机示例,我相信还有更多)可以让您在某种程度上实现自动化,但是我对他们没有任何经验。

答案 3 :(得分:1)

你的确可以,我的意思是,以编程方式 - 但这会绕过Reference.

  

4.4您不得开发多个应用程序来模拟或充当单个应用程序,或以其他方式访问Heroku服务以避免产生费用。

现在,我不确定这个:

  

因为节点是单线程应用程序,所以一旦我们开始从ios端到Web服务器获得更高级别的流量,这将是一个问题。

有一些讨论的线程,有一些有趣的答案:

Heroku's TOS

Clustering Node JS in Heavy Traffic Production Environment

另外,他们链接到这个视频,介绍了Node.js,它讲述了一些基准测试:

How to decide when to use Node.js?