[nodejs] node-schedule로 스케줄러 구현

sehannnnnnn·2022년 12월 8일
2

시작하기 앞서 프로젝트에 닥친 문제

내가 프로젝트에 활용하는 서울 공공데이터는 5분마다 새로운 인구 데이터를 반환한다.

문제가 하나 있는데
요 API가 근데 조금 느리다. 인구 데이터만 받아올 수 없기 때문에 전체 응답에서 인구데이터만 파싱하는 작업이 필요했고, 이러한 작업이 중간에 끼기 때문에 클라이언트에서 API를 요청했다간 앱 속도가 굉장히 느려질것 같았다.

5분마다 서버에서 API를 일괄적으로 실행하고 DB에 저장해 둔다면, 유저에 매 요청 마다 서울 도시데이터 API를 실행하지 않고, DB에 저장해둔 데이터를 전송해주는 방식으로 구현할 수 있겠다는 생각이 들었다.

스케줄러

서버 프로그램에서 특정 시간에 맞추어 어떤 동작을 수행하게 하는 것을 스케줄러 라고 한다. 이 이 용어도 처음 알아서 어떻게 구글링해야하는지 한참을 헤맸다.

node-schedule 모듈

node-schedule은 컴퓨터 내장 시간에 따라 동작 수행을 가능하게 하는 node.js 기반 스케줄러이다.
node-schedule 외에도

  • node-cron
  • agenda

등이 있지만, 가장 다운로드 빈도가 많은 node-schedule을 사용했다.

https://www.npmjs.com/package/node-schedule

node-schedule 적용 방법 예시

nodejs 실행 환경에서

const schedule = require('node-schedule');

const job = schedule.scheduleJob('42 * * * *', function(){
  console.log('The answer to life, the universe, and everything!');
});

위 코드는 매 42초 마다 콘솔에 글귀를 찍는다.
여기서 매 42초는 42초 간격이 아니다!
매 시침이 42초를 가리킬 때를 말하는 것이다!!

scheduleJob 함수는 첫번째 인자로 시간에 대한 문자열을 받고 두번째 인자로 수행할 콜백함수를 받는다.

  • 시간 문자열 사용법
  • 각 몇분 마다 , 몇 초 간격도 충분히 구현 가능하다.

Express 서버 실행 환경에서

  • ES6 module
//app.js
import { scheduleJob } from 'node-schedule';

const SCHEDULE_PORT = 8010;

...(코드 생략)...

app.listen(SCHEDULE_PORT, () => {
  //매 5분마다 수행!
  scheduleJob('*/5 * * * *', function() {
    writeTimeLog(); //실행할 함수입니다!
    fetchAllLiveData() //실행할 함수!
  })
})

nodejs Express 서버를 킨 상태에서 이 스케줄러를 사용하려면 app.listen() 안에 실행시킬 포트번호와 함께 콜백함수로 호출해 주어야한다.

//writeTimeLog.js
import { writeFile } from "fs";
import path from "path";

export const writeTimeLog = async () => {

  const curr = new Date();
  
  // 2. UTC 시간 계산
  const utc = 
        curr.getTime() + 
        (curr.getTimezoneOffset() * 60 * 1000);
  
  // 3. UTC to KST (UTC + 9시간)
  const KR_TIME_DIFF = 9 * 60 * 60 * 1000;
  const kr_curr = 
        new Date(utc + (KR_TIME_DIFF)).toLocaleString();

  // DB json 파일에 현재 시간 저장
  //파일 경로는 DB 디렉토리 내 timeLog.json이다.
  writeFile(path.resolve('../DB','timeLog.json'),JSON.stringify(kr_curr), (err) => {
    if (err) {
      console.log(err);
    } else {
      console.log(kr_curr, '실행완료!')
    }
  });
}

이렇게 현재 한국 시간을 파일에 저장하는 함수를 scheduleJob 를 통해 스케줄러에 등록해놓으면,
요렇게 5분 간격으로 현재 시간을 기록해둘 수 있다.

그 외 파일 저장 관련

  • fs 모듈을 활용해 파일을 수정할 때, 서버를 실행하는 app.js 하위 폴더 아래의 파일을 두면, nodemon이 수정을 파악해 서버를 재시작해버린다!
  • DB 디렉토리를 외부로 위치시키고, path 모듈을 이용해서 파일을 읽고 쓸 수

    있게 되었다!
profile
FE 개발자 준비생 블로그 🪐

0개의 댓글