현재 서비스 중인 애플리케이션의 기능 중 하나를 위해 이틀에 한번씩 정각쯤에 api를 실행해야 했습니다.
매번, 이를 처리하기 위해 서버를 키고 postman을 통해 api 호출하는 작업이 번거로워 이를 자동화하는 방법이 있을지 찾아봤어요.
Node는 이벤트 기반으로 작동하는 언어이기 때문에 처음에는 node event 등록, 실행 이런식으로 검색해보니 node-schedule 라이브러리를 통해 제가 원하는 작업을 할 수 있다는 것을 알았답니다.
우선 라이브러리를 설치해줍시다.
npm i node-schedule
해당 깃헙에 자세한 사용 방법이 나와 있으니, 참고하시고 제가 이용한 방법을 소개하겠습니다.
https://github.com/node-schedule/node-schedule
해당 라이브러리는 scheduleJob()을 이용해 편리하게 사용할 수 있습니다.
const schedule = require('node-schedule')
schedule.scheduleJob(scheduling-type, callback)
첫번째 인자로 전달되는 부분은 스케줄링 타입을 지정할 수 있습니다.
총 세가지의 타입이 있지만 두 가지만 소개하겠습니다.
Cron-style Scheduling
저는 이 방법을 채택해서 프로젝트에 적용했습니다.
해당 방법은 해당 시각이 되면 콜백 함수를 실행하게 됩니다. 주기가 아닙니다.
가령, 30초가 되는 시점에 실행이 되는 것인지 서버를 키고 30초 간격마다 실행되는 것이 아닙니다.
* * * * * *
/* 순차적으로
second(0-59)
minute(0-59)
hour(0-23)
day(1-31)
month(1-12)
day of week(0-7)
를 값으로 가집니다.
*/
매 30초마다 실행되는 함수는 다음과 같이 만들 수 있습니다.
schedule.scheduleJob('30 * * * * *', () => {
console.log('schedule is executed')
})
매일 오후 3시 30분에 실행되는 함수는 어떻게 만들면 될까요?
schedule.scheduleJob('* 30 15 * * *', () => {
console.log('schedule is executed')
}) (x)
schedule.scheduleJob('0 30 15 * * *', () => {
console.log('schedule is executed')
}) (o)
위의 방법은 초가 들어가야할 자리에 *를 채워넣었기 때문에 매 초마다 출력을 하게 됩니다.
3시 30분 0초, 3시 30분 1초, 3시 30분 2초, ... 모두 말이죠.
저는 매 정각 5분에 실행 시키기 위해 다음과 같이 작성했습니다.
schedule.scheduleJob('0 5 0 * * *', () => {
console.log('schedule is executed')
})
Date-based Scheduling
Date 객체를 이용해서 스케줄을 지정해줄 수도 있습니다. 가령, 데이터베이스에 존재하는 유저들이 제각기 알림을 "xx.xxx 시각에 받고 싶다"라고 한다면 해당하는 유저들의 저장된 알림 시각 1시간, 2시간 전에 동일한 로직으로 콜백함수를 실행시켜줄 수 있다는 이야기입니다.
2022-3-15에 실행시키는 작업
const date = new Date(2022, 3, 15, 0, 0, 0)
schedule.scheduleJob(date, () => {
console.log('schedule is executed')
})
db에 저장된 유저의 예약 시간 2시간 전에 실행시키는 작업
// userReservedTime => 디비에 저장된 유저의 예약 시간을 담은 변수
const date = new Date(userReservedTime)
schedule.scheduleJob(date.getHours() - 2, () => {
console.log('schedule is executed')
})
해당하는 schedule을 서버가 켜지는 곳과 분리하기 위해 utils 폴더에 만들어 exports하고 이를 index.js에서 불러오는 것으로 구현하겠습니다.
utils/schedule.js
const schedule = require('node-schedule')
const job = schedule.scheduleJob('0 5 0 * * *', () => {
// 실행시켜야할 콜백 함수 호출
console.log('add your callback functions')
})
module.exports = job
index.js
require('./utils/schedule')
끝입니다. 깃헙에 보면 job 변수에 담아서 불러오는데 job.cancel() 할 일이 없기 때문에 따로 변수에 담지는 않았습니다.
감사합니다. 🙇♂️
node-schedule 라이브러리를 이용해 콜백 함수를 특정 시각에 호출해 자동화하는 방법에 대해 정리했습니다:)