nestjs/bull 를 쓰다, 동시성(concurrency) 옵션에 관련한 이슈를 발견하여 포스팅해본다.
nestjs/bull queue에서는 아래처럼 concurrency를 설정할 수 있다.
# nestjs
@Processor('test-queue')
export class testQueueConsumer {
@Process({
name: 'someJob',
concurrency: 5,
})
async processSomeJob(
...
이슈사항
nestjs/bull queue를 사용하다가
concurrency를 설정하지 않았음에도 불구하고 여러 job이 동시에 작동되며,
concurrency를 설정할 경우 설정값보다 훨씬 더 많은 개수의 job이 동시에 작동되는 현상을 확인했다.
*nestjs/bull을 쓰다 발견했을뿐, bull 라이브러리 자체의 이슈이다.
결론먼저
동일한 큐 안에 대해 여러 Process를 정의하면, 각 소비자의 동시성 설정이 합산된다.
그 합산한 갯수만큼 실제 동시성이 결정되게 된다.
상세 이슈 분석
Bull 라이브러리에서의 현재 설계 구조에서는 동시성이 process 아닌 processor 수준에서 관리된다.
그래서, 동일한 큐에 대해 여러 process를 호출할떄마다, 각 호출의 동시성 설정이 processor에 합산된다.
const queue = new Queue('my-queue');
queue.process('task1', 5, async (job) => {
// task1 처리
});
queue.process('task2', 5, async (job) => {
// task2 처리
});
예를들어 위와 같이 소비자를 정의한 경우, task1과 task2의 동시성 설정이 5이므로,
이 큐의 총 동시성이 10이 된다.
task1을 작동하던 task2를 작동하던, 동시에 10개가 작동하게 된다.
관련 git issue
Can't define a concurrency with a 0 value using the @Processor decorator #258
Multiple named consumers are sharing concurrency settings #867
Processors with multiple processes inconsistently process jobs #1813
*nestjs/bull 의 공식 문서에서 또한 경고하고 있는 내용이다.
해결 방법
1. 여러 process중 하나에만 concurrency를 1로, 나머지는 concurrency를 0으로. 설정
이렇게 될 경우 여러 process가 추가된다 하더라도 동시성 1을 유지할 수 있다.
@Process({ name: NAMED_JOB_1, concurrency: 1 })
async updateJob1(job: Job<any>) { }
@Process({ name: NAMED_JOB_2, concurrency: 0 })
async updateJob2(job: Job<any>) { }
Can't define a concurrency with a 0 value using the @Processor decorator #258
2. 여러 작업들에 대해 한 Process로 처리하기.
이럴경우 무조건 한 process만 정의하기에 동시성을 유지할 수 있다.
@Processor('SOCIAL_ENTITY_JOBS')
export class Processor {
constructor() {}
@Process({ name: '*', concurrency: 1 })
async processJob(job: Job<unknown>) {
switch (job.name) {
case "create_post":
return this.create_post(job);
case "update_post":
return this.update_post(job);
}
}
async create_post(job: Job<unknown>) {
// handling logic is here
}
async update_post(job: Job<unknown>) {
// handling logic is here
}
}
Global concurrency limit #1853
다만, 여전히 process별 동시성 설정은 불가능하다.
bull을 사용할 때 특정 process만의 동시성을 관리하고 싶으면 해당 process를 처리하는 큐 자체를 분리하던가 해야한다.
댓글