【问题标题】:node.js calculating bandwidth usage by domainnode.js 按域计算带宽使用情况
【发布时间】:2012-04-11 05:00:59
【问题描述】:

如何使用 node.js 作为 Web 服务器监控每个域的带宽使用情况?

有人知道我没有遇到过的 API 调用吗?

或者其他人在您按带宽收费的多租户环境中使用的模块或其他方法?

更新:

有谁知道可以放置在任何 Web 服务器(node.js、apache 等)前面的轻量级代理/服务器,可以通过检查域来记录这些带宽统计信息?

【问题讨论】:

  • 您使用的是 Express、Connect、自定义代码吗?
  • 未锁定在任何模块或框架中。只是想知道如何使用node.js作为Web服务器来实现它。
  • 没有执行此操作的 API 调用。您是控制 Node.js Web 服务器,还是监控您托管的其他人的应用程序?如果是前者,我可以建议一些代码。如果是后者,我可以推荐一个代理。
  • 目前它将是一个 SaaS 多租户应用程序,我们可以完全控制从操作系统开始的整个堆栈。但我也对您对后者的想法感兴趣,因为我们将来可能希望为客户托管 nodejs 应用程序。

标签: node.js limit monitoring bandwidth


【解决方案1】:

在不修改 node.js 核心的情况下,最好的选择似乎是使用 bytesRead 和 bytesWritten 变量在套接字级别跟踪它。

这实际上比仅测量 http 请求/响应字符串的大小更准确,因为某些其他带宽跟踪器会计算传输的数据。

您有 2 个选项:1) 记录每个请求的字节数或 2) 记录 TCP 连接关闭时的字节数。

在请求级别登录将提供可能有用的实时数据。但是,这可能会减慢速度,具体取决于您实现日志记录的方式。最好将其保存在内存中并每隔一段时间将其转储到磁盘/数据库中。

在请求级别记录:

var http = require('http');
var server = http.createServer(function (req, res) {
  // setup a counter for bytes already logged
  req.connection.bytesLogged = (req.connection.bytesLogged || 0);

  // output the bytes read by the socket
  console.log('Socket [' + req.connection.remoteAddress + '] [' + req.headers.host + '] - Bytes Read: ' + req.connection.bytesRead);

  // calculate the bytes of the request (includes headers and other tcp overhead - more realistic)
  req.bytes = req.connection.bytesRead - req.connection.bytesLogged;
  // output the bytes size of the request (note this is calculated after the TCP packets have been collected from the network and parsed by the HTTP parser
  console.log('Request [' + req.connection.remoteAddress + '] [' + req.headers.host + '] - Bytes: ' + req.bytes);

  // log the bytes to a memory array, DB or disk (implementation not shown)
  // [code here]

  // add the request bytes to the counter
  req.connection.bytesLogged = req.connection.bytesLogged + req.bytes;

  // normal http server processing like return document or file
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('ok');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.1.1:1337/');

在套接字级别记录:

var http = require('http');
var server = http.createServer(function (req, res) {

  // create some variables for data we want to log
  //
  // due to the way node.js works the remoteAddress and remotePort will not
  // be available in the connection close event
  // we also need to store the domain/host from the http header because the http
  // request also won't exist when the connection close event runs
  var remoteAddress = req.connection.remoteAddress;
  var remotePort = req.connection.remotePort;
  var host = req.headers.host;
  var connection = req.connection;

  // output bytes read by socket on each request
  console.log('HTTP Request [' + remoteAddress + ':' + remotePort + '] [' + host + '] - connection Bytes Read: ' + connection.bytesRead);

  // setup handle for connection close event
  //
  // to avoid the handle being added multiple times we add the handle onto
  // the connection object which will persist between http requests
  //
  // we store the handler so we can check whether it has already been added
  // to the connection listeners array - a less robust alternative would be to
  // add a flag like connection.closeHandleAdded = true
  connection.handle = connection.handle || {};
  if (!connection.handle.onconnectionClose) {
    connection.handle.onconnectionClose = function() {
      onconnectionClose(remoteAddress, remotePort, host, connection.bytesRead);
    }
  }

  // check whether the close handle has already been added to the connection
  // if not add it
  if(connection.listeners('close').indexOf(connection.handle.onconnectionClose) == -1)
  {
    // attach handler to connection close event
    connection.on('close', connection.handle.onconnectionClose);
    // set connection idle timeout to 5 secs for testing purposes (default is 2min)
    connection._idleTimeout = 5000;
  }

  // process http request as required
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('ok');

}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.1.1:1337/');

function onconnectionClose (remoteAddress, remotePort, host, bytesRead) {
   console.log('connection Closed [' + remoteAddress + ':' + remotePort + '] [' + host + '] - connection Bytes Read: ' + bytesRead);
}

【讨论】:

    【解决方案2】:

    你应该看看Http Trace

    它是一个 node.js 模块,用于捕获、解码和分析 HTTP 和 WebSocket 流量。 它可以找到每个请求的大小和域,因此通过一些调整,您应该能够在这里完成您想要完成的工作。

    它在我的带有节点 v0.6.15 的 Ubuntu 服务器上运行良好,我所要做的就是“apt-get install libpcap0.8-dev”。

    【讨论】:

    • 这似乎只是记录响应正文中返回的消息的大小,而不是准确测量带宽,包括所有流出(和可选)的流量。
    【解决方案3】:

    尝试使用此模块测量 HTTP 响应/请求:https://github.com/hex7c0/transfer-rate

    数据通过套接字在客户端和服务器之间发送。每个 HTTP 响应/请求都有自己的套接字。模块在套接字中获取发送字节(socket.bytesWritten 用于响应,socket.bytesRead 用于请求)。通过命令(process.hrtime(start))计算发送数据的时间。然后,我们将结果除以得到实际的传输速率。

    【讨论】:

      猜你喜欢
      • 2014-02-01
      • 1970-01-01
      • 2013-02-19
      • 1970-01-01
      • 1970-01-01
      • 2017-05-07
      • 1970-01-01
      • 2011-05-09
      • 2013-01-06
      相关资源
      最近更新 更多