我正在集群模式下运行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?