本文介绍了表达-一次将一个请求限制为一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 express 来构建API应该在内部使用.该请求之一触发了服务器上的繁重进程,应从中返回CSV.此过程可能需要10分钟以上.

I'm using express to build a API that should be used internally. One of the request trigger an heavy process on the server and should return a CSV out of that. This process might take more than 10 minutes.

为了不使服务器超载,我想限制此API的调用并使之调用,以使该进程不会终止,因此我们无法再次请求相同的URL.

To not overloading the server I want to restrict the call of this API and make it so that, since the process isn't terminated, we can't request the same URL again.

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

For this I tried to use express-rate-limit with the following configuration:

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分钟后重试该请求,如果没有任何答案,可以吗?

But it seems that the 'max request' is reached every time after exactly 2 mins even if I start only once. I suspect the browser to retry the request after 2 min if doesn't get any answer, is it possible?

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

I would like that this request doesn't have any retry-strategy and that the only way the max request is reached is by manually asking the server to execute this request 2 times in a row.

谢谢.

这是我的完整代码:

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

推荐答案

我找到了此GitHub问题的答案谢谢: https://github.com/expressjs/express/issues/2512 .

I found the answer thank's to this GitHub issue: https://github.com/expressjs/express/issues/2512.

TLDR:我添加了 request.connection.setTimeout(1000 * 60 * 30); 以避免每2分钟触发一次请求.

TLDR: I added request.connection.setTimeout(1000 * 60 * 30); to avoid firing the request every 2 minutes.

但是考虑到我在问题中编写的代码,@ Paul的建议仍然值得考虑.

But considering the code I wrote inside my question, @Paul's advices are still good to be taken into account.

这篇关于表达-一次将一个请求限制为一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-28 13:12
查看更多