私は使っています
express
内部で使用されるAPIを構築します。リクエストの1つがサーバーで重いプロセスをトリガーし、その中から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 件
関連記事
- 静的バンドルからExpressバックエンドにリクエストをプロキシすると、NginXはPOSTリクエスト本文の受け渡しに失敗します
- ExpressJSで空のリクエスト本文を取得しています
- ReactJs、Express、Axios、リクエストをサーバーに送信してからクライアントに応答する
- React and Expressでブロックされたクロスオリジンリクエスト
- ボタンから投稿リクエストを呼び出す方法は?ノードエクスプレス
- 要求はまだ終了していませんmongoDBおよびExpressのエラー
- エクスプレスからmongoDBへのリクエストの投稿
- ノードJS Expressサーバー:すべての正しいヘッダーがある場合でも、クロスオリジンリクエストがブロックされました
- 1秒あたりのAWS KMSリクエストの制限の回避策
関連した質問
- いくつかのIPを除いてすべての人にミドルウェアを適用する必要がありますが、ルート外でreqとresを取得できません。どうすれば適用できますか?
- httpsクライアントのサーバーに画像を表示するにはどうすればよいですか?
- SyntaxError:モデルでのJSON入力の予期しない終了
- 機関砲を備えたベンチマークエクスプレスAPI
- __dirnameが定義されていません
- すべてのプロパティを必要かどうかをマークするJoi
- Expressjs別のリクエストが処理されている場合にリクエストを防ぐ方法は?
- TypeError:未定義のnodejs expressmvcのプロパティ 'render'を読み取れません
- ERR EMPTY RESPONSE
- ルートは空の応答を送信しています
このGitHubの問題(https://github.com/expressjs/express/issues/2512)への感謝の答えが見つかりました。
TLDR:
request.connection.setTimeout(1000 * 60 * 30);
を追加しました 2分ごとにリクエストを送信しないようにします。しかし、私の質問の中に書いたコードを考えると、@ Paulのアドバイスは考慮に入れるのにまだ良いです。