简体   繁体   English

node.js 按域计算带宽使用

[英]node.js calculating bandwidth usage by domain

How can I monitor the bandwidth usage of each domain using node.js as the web server? node.js作为web服务器,如何监控各个域的带宽使用情况?

Does anyone know of an API call I haven't come across to do this?有谁知道我没有遇到过的 API 电话吗?

Or a module or another method which others have used in a multi-tenant environment where you are charging by bandwidth?或者其他人在按带宽收费的多租户环境中使用的模块或其他方法?

Update:更新:

Does anyone know of a lightweight proxy / server which could be put in front of any web server (node.js, apache, etc) which can record these bandwidth stats by inspecting the domain?有谁知道可以放在任何 web 服务器(node.js、apache 等)之前的轻量级代理/服务器,它可以通过检查域来记录这些带宽统计信息?

Without modifying the node.js core, the best option seems to be to track it at the socket level using the bytesRead and bytesWritten variables.在不修改 node.js 核心的情况下,最好的选择似乎是使用 bytesRead 和 bytesWritten 变量在套接字级别跟踪它。

This is actually more accurate than merely measuring the size of http request / response string as some other bandwidth trackers do to calculate data transferred.这实际上比仅测量 http 请求/响应字符串的大小更准确,因为一些其他带宽跟踪器计算传输的数据。

You have 2 options: 1) log the bytes at each request OR 2) log the bytes on the TCP connection close.您有 2 个选项:1) 记录每个请求的字节数或 2) 记录 TCP 连接关闭时的字节数。

Logging on the request level will provide real-time data which could be useful.登录请求级别将提供可能有用的实时数据。 However, it is likely to slow things down depending on how you implement the logging.但是,根据您实现日志记录的方式,它可能会减慢速度。 It is probably best to keep it in memory and dump it to disk / DB every so often.最好将其保存在 memory 中,并经常将其转储到磁盘/数据库中。

Log at request level:在请求级别登录:

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/');

Log at socket level:在套接字级别登录:

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);
}

You should have a look at Http Trace .你应该看看Http Trace

It is a node.js module that captures, decodes and analyses HTTP and WebSocket traffic.它是一个 node.js 模块,可以捕获、解码和分析 HTTP 和 WebSocket 流量。 It can find the size and domain for each request, so with some tweaking, you should be able to do what you want to accomplish here.它可以找到每个请求的大小和域,因此通过一些调整,您应该能够在这里完成您想要完成的事情。

It is working well on my Ubuntu server with node v0.6.15, all I had to do was to "apt-get install libpcap0.8-dev".它在我的 Ubuntu 节点 v0.6.15 服务器上运行良好,我所要做的就是“apt-get install libpcap0.8-dev”。

Try to use this module to measure HTTP response/request: https://github.com/hex7c0/transfer-rate尝试使用此模块测量 HTTP 响应/请求: https://github.com/hex7c0/transfer-rate

Data is sent between a client and a server by a socket.数据通过套接字在客户端和服务器之间发送。 Each HTTP response/request has their own socket.每个 HTTP 响应/请求都有自己的套接字。 The module gets sent-byte in the socket ( socket.bytesWritten for the response, and socket.bytesRead for the request).该模块在套接字中获取发送字节(用于响应的socket.bytesWritten ,用于请求的socket.bytesRead )。 The time for sending the data is calculated by a command ( process.hrtime(start) ).发送数据的时间由命令 ( process.hrtime(start) ) 计算。 Then, we divide the results to get the actual transmitted rate.然后,我们将结果除以得到实际传输速率。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM