Javascript 在expressjs中,如何限制可以同时发出请求的用户数量?
我的代码只是一个普通的应用程序:Javascript 在expressjs中,如何限制可以同时发出请求的用户数量?,javascript,node.js,express,Javascript,Node.js,Express,我的代码只是一个普通的应用程序: app .use(sassMiddleware({ src: __dirname + '/sass', dest: __dirname + '/', // This line controls sass log output debug: false, outputStyle: 'compressed' })) // More libraries ... .get('/', au
app
.use(sassMiddleware({
src: __dirname + '/sass',
dest: __dirname + '/',
// This line controls sass log output
debug: false,
outputStyle: 'compressed'
}))
// More libraries
...
.get('/', auth.protected, function (req, res) {
res.sendfile(__dirname + '/views/index.html');
})
.post('/dostuff', auth.protected, function (req, res) {
console.log(req.body)
res.redirect('back')
child = require('child_process').spawn(
'./script.rb',
['arguments'],
{ stdio: ['ignore', 'pipe', 'pipe'] }
);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stdout);
})
我最初的目标是将/dostuff可以生成的生成数量限制为单个实例。我在想,也许有一种简单的方法可以限制整个应用程序的用户数量,但似乎找不到
我试图寻找一些会话限制机制,但也找不到,只有各种各样的速率限制,但我不认为这是我想要的
由于应用程序在docker中运行,我使用iptalbes限制端口上的tcp连接数,但这已被证明不太理想,因为应用程序在已建立
状态下保留一些连接,从而防止从一个用户到另一个用户的有效切换
所以。。。有什么程序化的方法吗
更新
该应用程序不是api服务器/dostuff
实际上是由用户从网页触发的。这就是为什么简单的利率限制不是最好的选择。ruby脚本的执行时间也是可变的
回答
根据@jfriend00给出的以下答案,通过修复我发现的几个逻辑错误:
.post('/dostuff*', auth.protected, function (req, res) {
console.log(req.body)
if (spawnCntr >= spawnLimit) {
res.status(502).send('Server is temporarily busy');
console.log("You already have process running. Please either abort the current run or wait until it completes".red)
return;
}
let childClosed = false
function done () {
if (!childClosed) {
--spawnCntr;
childClosed = true;
}
}
++spawnCntr;
child = require('child_process').spawn(
blahblah
);
child.on('close', done);
child.on('error', done);
child.on('exit', done);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stdout);
res.redirect('back');
})
我仍然会接受他的回答,尽管这对我帮助很大 您可以使用node package Express Rate Limit- 对于仅API的服务器,速率限制器应应用于所有请求:
var RateLimit = require('express-rate-limit');
app.enable('trust proxy'); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS if you use an ELB, custom Nginx setup, etc)
var limiter = new RateLimit({
windowMs: 15*60*1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
delayMs: 0 // disable delaying - full speed until the max limit is reached
});
// apply to all requests
app.use(limiter);
var RateLimit = require('express-rate-limit');
app.enable('trust proxy'); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS if you use an ELB, custom Nginx setup, etc)
var apiLimiter = new RateLimit({
windowMs: 15*60*1000, // 15 minutes
max: 100,
delayMs: 0 // disabled
});
// only apply to requests that begin with /api/
app.use('/api/', apiLimiter);
对于“常规”web服务器(例如,任何使用express.static()的服务器),速率限制器应仅适用于某些请求:
var RateLimit = require('express-rate-limit');
app.enable('trust proxy'); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS if you use an ELB, custom Nginx setup, etc)
var limiter = new RateLimit({
windowMs: 15*60*1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
delayMs: 0 // disable delaying - full speed until the max limit is reached
});
// apply to all requests
app.use(limiter);
var RateLimit = require('express-rate-limit');
app.enable('trust proxy'); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS if you use an ELB, custom Nginx setup, etc)
var apiLimiter = new RateLimit({
windowMs: 15*60*1000, // 15 minutes
max: 100,
delayMs: 0 // disabled
});
// only apply to requests that begin with /api/
app.use('/api/', apiLimiter);
您可以保留一个简单的计数器,显示同时有多少
spawn()
操作在进行中,如果新请求进来,并且您当前超过该限制,您只需返回一个502错误(服务器暂时繁忙)
注意:您问题中的代码没有将
child
声明为一个局部变量,看起来像是一个等待发生的bug。我的答案有用吗?或者您还需要什么吗?@DamienGold更新了我的答案,解释了为什么我认为在这种情况下利率限制会很笨拙。我更新了我的答案。第二种选择应该适合你。如果是的话,把它标记为解决方案。这看起来不像是一个利率限制问题。生成的进程运行的时间不确定,因此无法使用定时速率限制器一次仅管理一个生成的进程,而不大量夸大时间限制,从而使您甚至无法执行一个请求,并且在请求完成时执行另一个请求。这根本不是一个速率限制问题,就连OP也已经说过。我之所以不将child声明为函数变量,是因为我需要能够从另一个.get
请求终止它。@user3081519-那么spawnLimit
必须是1
,因为如果它是任何其他值,然后,在生成第二个变量时,您将覆盖子变量。