ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Bull 라이브러리 (Node.js)
    TIL 2024. 7. 19. 22:15

     

     > 최종 프로젝트 진행 전 기획 단계에서 사전학습으로 Bull 라이브러리에 대해 간략하게 조사해보았다.

     

    학습 키워드: Node.js, Bull Queue

     

    1. Bull

    1) What is it?:

     Bull은 Redis 기반의 Queue 시스템이다. Redis에서도 자체적으로 Queue를 지원하지만, low level의 디테일을 신경 쓸 필요 없도록 API화 시켜둔 라이브러리라고 할 수 있겠다.

     

    2) How does it work?:

     

    npm install bull --save

     

     (NPM 설치)

     

    // my-first-queue 가 instantiation name이 된다.
    const bullQueue = new Bull('my-first-queue');

     

     Bull 클래스 생성자에 인자로 instance 이름을 넘겨주는 식으로 작업 queue를 생성할 수 있다.

     

     

    Figure 1. A job's lifecycle

     

    // queue에 job 추가
    const job = await bullQueue.add({
      foo: 'bar',
    });
    
    // 두 번째 인자로 option 지정, 아래는 가능한 key 목록
    {
      lifo: true, // LIFO 작업. Queue의 맨 앞에 추가함
      delay: 5000, // 작업 대기 최소 시간(단위: ms). 시간이 지나면 queue의 맨 앞에 추가됨 
      priority: 3, // 우선 순위. 1이 최우선이며 숫자가 커질수록 우선순위 낮음.
      repeat: { // 반복 1
        every: 10000, // 10초마다 반복
        limit: 100, // 100번 반복
      }
      repeat: { // 반복 2
        cron: '15 3 * * *' // 매일 3:15 AM 에 한 번 실행
      }
    }

     

     Bull queue에 작업을 추가해주는 역할을 하는 프로그램을 producer라고 부른다. 작업 추가 함수 add는 첫 번째 인자로 처리할 job 데이터인 JS 객체를 받는다. 이 객체는 직렬화(serialize)가 가능해야 하며, Redis에 저장되어야 하기 때문에 JSON.stringify를 통해 string으로 변환할 수 있는 객체여야 한다. 두 번째 인자로는 option 객체를 받는데, 넘겨받은 job의 타입을 key-value 형태로 정의한다.

     

    bullQueue.process(async (job) => {
      return doSomething(job.data); // returned value is stored in the job, which can then be accessed in 'completed' event
    });
    
    const doSomething = (data) => {
      return data.value + 5;
    }

     

     Bull queue에 있는 작업을 처리하는 process 함수를 위와 같이 정의한 Node 프로그램을 consumer 혹은 worker 라고 부른다. Process 함수는 Worker가 쉴 때마다 호출이 되고, 작업 큐에 있는 모든 작업이 완료될 때까지 연속해서 동작하게 된다. 공식 문서에서는 process 함수를 async로 정의하기를 권장하고 있다. 만약 async await을 사용할 수 없는 상태라면 Promise를 사용하여 결과를 반환하는 식으로 비슷한 결과를 얻을 수 있는 구조로 구현 할 수도 있다.

     

     Job의 진행도를 추적해야하는 경우가 있을 수 있는데, 그런 경우에는 위 process 함수 안에서 job의 progress method를 이용하여  job.progress(someNumberValue) 의 형태로 정의 할 수 있다.

     

    bullQueue.on('completed', (job, result) => { // local
      console.log(`Job completed with result ${result}`);
    });
    
    bullQueue.on('global:completed', (jobId) => { // global
      console.log(`Job with id ${jobId} has been completed`);
    });

     

     앞서 process 함수에서 처리 결과를 반환할 수 있다고 했는데, 그 때 처리된 결과는 'completed' 이벤트의 listener를 정의해서 콜백의 두 번째 인자인 result를 이용하여 조회할 수 있다. 이러한 이벤트 listener는 local 혹은 global의 형태로 정의할 수 있으며, local은 하나의 queue를, global은 모든 Bull queue를 대상으로 listening을 하게 된다. 사용 가능한 이벤트 목록은 링크를 참고하자.

     

     

    bullQueue.process('someJobType', processSomeType);
    bullQueue.process('otherJobType', processOtherType);
    
    await bullQueue.add('someJobType', { foo: 'bar' });
    await bullQueue.add('otherJobType', { bar: 'barbar' });
    
    const processSomeType = (job, done) => {
      // do something for someJobType
    }
    
    const processOtherType = (job, done) => {
      // do something for otherJobType
    }

     

     Named jobs: 위와 같이 job 타입 이름별로 다른 process 함수가 처리하도록 정해줄 수도 있다. add 시에 첫 번째 인자로 동일한 job 이름을 지정해주면 된다. 

     

     

     

     

     

     

    --

     

    REFERENCES:

     

     

    최종 프로젝트 Game Server 기술 Insight | Notion

    들어가며

    teamsparta.notion.site

     > 게임 서버 최종 프로젝트 기술 Insight

     

     

    bull

    Job manager. Latest version: 4.15.1, last published: 15 days ago. Start using bull in your project by running `npm i bull`. There are 940 other projects in the npm registry using bull.

    www.npmjs.com

     > NPM, "bull" 라이브러리

     

    Welcome to Bull’s Guide

    Premium Queue package for handling distributed jobs and messages in NodeJS.

    optimalbits.github.io

     > "Welcome to Bull's Guide", Bull Queue 공식 가이드 (OptimalBits)

    728x90
Designed by Tistory.