express - 一次限制一个请求

时间:2018-05-25 11:27:49

标签: node.js express rate-limiting

我使用express构建应在内部使用的API。其中一个请求会在服务器上触发一个繁重的进程,并且应该返回一个CSV。此过程可能需要10分钟以上。

为了不重载服务器,我想限制对此API的调用并使其成为可能,因为该过程未终止,我们无法再次请求相同的URL。

为此,我尝试使用express-rate-limit以下配置:

new RateLimit({
    windowMs: 30 * 60 * 1000, // 30 minutes
    max: 1,
    delayMs: 0, // disabled
    message: 'Their is already a running execution of the request. You must wait for it to be finished before starting a new one.',
    handler: function handler(req, res) {
        logger.log('max request achieved');
        logger.log(res);
    },
});

但似乎最大请求'即使我只开始一次,也会在每2分钟后到达。我怀疑浏览器会在2分钟后重试请求,如果没有得到任何答案,是否可能?

我希望此请求没有任何retry-strategy,并且达到max request的唯一方法是手动要求服务器连续执行此请求2次。

感谢'第

编辑

这是我的完整代码:

const app = express();
const port = process.env.API_PORT || 3000;

app.enable('trust proxy');

function haltOnTimedout(req, res, next) {
    if (!req.timedout) { next(); }
}

app.use(timeout(30 * 60 * 1000)); // 30min
app.use(haltOnTimedout);

app.listen(port, () => {
    logger.log(`Express server listening on port ${port}`);
});

// BILLING
const billingApiLimiter = new RateLimit({
    windowMs: 30 * 60 * 1000, // 30 minutes
    max: 1,
    delayMs: 0, // disabled
    message: 'Their is already a running execution of the request. You must wait for it to be finished before starting a new one.',
    handler: function handler(req, res) {
        logger.log('max request achieved');
    },
});

app.use('/billing', billingApiLimiter);
app.use('/billing', BillingController);

route的代码:

router.get('/billableElements', async (request, response) => {
    logger.log('Route [billableElements] called');
    const { startDate } = request.query;
    const { endDate } = request.query;
    try {
        const configDoc = await metadataBucket.getAsync(process.env.BILLING_CONFIG_FILE || 'CONFIG_BILLING');
        const billableElements = await getBillableElements(startDate, endDate, configDoc.value);
        const csv = await produceCSV(billableElements);
        logger.log('csv produced');
        response.status(200).send(`${csv}`);
    } catch (err) {
        logger.error('An error occured while getting billable elements.', err);
        response.status(500).send('An internal error occured.');
    }
});

1 个答案:

答案 0 :(得分:0)

我发现答案谢谢这个GitHub问题:https://github.com/expressjs/express/issues/2512

TLDR:我添加printA()以避免每2分钟触发一次请求。

但考虑到我在问题中写的代码,@ Paul的建议仍然很好被考虑在内。