0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NestJSで特定エンドポイントの並行実行数を制限する

Last updated at Posted at 2024-08-21

はじめに

NestJSでは、NestJS公式のThrottleパッケージを使用すれば設定以上の頻度で来るアクセスをブロックできますが、その場合溢れたアクセスはエラーでクライアント側に返ってしまいます。

あくまでも並行実行数を絞りつつ、すべてのアクセスを正常に捌きたいというようなケースについては公式の方法は用意されていませんが、独自にインターセプターを作ることで対応することが可能です。

実装

カスタムインターセプターの作成

まず、並行処理を制限するカスタムインターセプターを作成します。
このインターセプターでは p-limitライブラリを使用して、並行処理の数を制限しています。

import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';
import pLimit from 'p-limit';

@Injectable()
export class ConcurrencyInterceptor implements NestInterceptor {
  private limit;

  constructor(concurrency: number) {
    this.limit = pLimit(concurrency);
  }

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return new Observable((observer) => {
      this.limit(() => next.handle().toPromise())
        .then((result) => {
          observer.next(result);
          observer.complete();
        })
        .catch((err) => {
          observer.error(err);
        });
    });
  }
}

コントローラメソッドにインターセプターを適用

次に、作成したConcurrencyInterceptorを、 @UseInterceptors デコレーターを使ってコントローラの特定のメソッドに適用します。

Copy code
import { Controller, Post, UseInterceptors } from '@nestjs/common';
// fromは自分がインターセプターをおいた場所にする
import { ConcurrencyInterceptor } from './concurrency.interceptor';

@Controller('your-endpoint')
export class AppController {
  @Post()
  @UseInterceptors(new ConcurrencyInterceptor(3)) // ★例えば並行処理を3に制限
  async yourEndpointHandler() {
    // ハンドラーのロジック
  }
}

終わりに

このように、インターセプターを使うことでエンドポイントごとに柔軟にconcurrencyを設定できるようになります。
Throttlingと違い、同時実行制限をしつつリクエストの失敗を防げるため便利です。
※別の言い方をすると、ConcurrencyInterceptorはエンドポイントに対するキューイングのようなイメージに近い、ということです。

ただ、言うまでもないですが消化スピードより速いペースで永遠にリクエストが入り続けるとこの方法は破綻するので、そのようなケースではThrottlingによる制限の方を検討したほうがいいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?