如何在node.js集群模式下基于IP的API速率限制?

时间:2019-05-13 09:28:50

标签: node.js express nginx rate-limiting

我正在集群模式下运行node.js / express / socket.io应用程序。 我为主进程运行一个外部服务器,为工作人员运行内部服务器,如下面的代码所示。

if (cluster.isMaster) {

var workers = [];

var spawn = function(i) {
    workers[i] = cluster.fork();

    // Optional: Restart worker on exit
    workers[i].on('exit', function(code, signal) {
        console.log('Process exited! respawning worker no: ', i);
        spawn(i);
    });
  };

  // Spawn workers.
for (var i = 0; i < numCPUs; i++) {
    spawn(i);
}


var worker_index = function(ip, len) {
    return farmhash.fingerprint32(ip) % len; // Farmhash is the fastest and works with IPv6, too
};

// Create the outside facing server listening on our port.
var server = net.createServer({ pauseOnConnect: true }, function(connection) {

  //!!!! the connection.remoteAddress causes issues with reverse proxy, however here not important as socket.io is used only for a global signalling to all clients
  // console.log(connection.remoteAddress);
    var worker = workers[worker_index(connection.remoteAddress, numCPUs)];
    worker.send('sticky-session:connection', connection);
}).listen(port);

console.log('***************************************');
console.log('listening EXTERNALLY http://localhost:' + port);
console.log("This system has " + numCPUs + " virtual or real CPUs");
console.log('***************************************');
connection.remoteAddress // --> this is 127.0.0.1

} else {

// all worker processes enter the app from server.js
require("./server.js");
}

然后在server.js中,根据系统上可用的内核数启动该服务器。

const rateLimit = require('express-rate-limit');
...
app.enable("trust proxy"); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
...
app.use('/api/', apiLimiter); // --> this does not work as the real IP is not available
...

//startup the HTTP server
 server.listen(0, 'localhost', function(err) {
     console.log('***************************************');
console.log('***************************************');
  console.log('listening INTERNALLY http://localhost:0');
console.log('***************************************');


});

使用此代码,node.js的API限制(express-rate-limit)不起作用。我怀疑这是因为IP在内部服务器(127.0.0.1,localhost)上始终是相同的。

创建http服务器后,我可以使用以下命令获取真实IP:

req.headers['x-real-ip'] ||  req.connection.remoteAddress;

但这在创建http服务器之前不起作用,但是我需要使用它来启用API限制器。

不知何故,我需要传递来自外部服务器(似乎是TCP服务器)的IP地址。 有没有一种方法可以在创建http服务器之前一开始就捕获真实IP?

0 个答案:

没有答案