내가 프로젝트에 활용하는 서울 공공데이터는 5분마다 새로운 인구 데이터를 반환한다.
문제가 하나 있는데
요 API가 근데 조금 느리다. 인구 데이터만 받아올 수 없기 때문에 전체 응답에서 인구데이터만 파싱하는 작업이 필요했고, 이러한 작업이 중간에 끼기 때문에 클라이언트에서 API를 요청했다간 앱 속도가 굉장히 느려질것 같았다.
5분마다 서버에서 API를 일괄적으로 실행하고 DB에 저장해 둔다면, 유저에 매 요청 마다 서울 도시데이터 API를 실행하지 않고, DB에 저장해둔 데이터를 전송해주는 방식으로 구현할 수 있겠다는 생각이 들었다.
서버 프로그램에서 특정 시간에 맞추어 어떤 동작을 수행하게 하는 것을 스케줄러 라고 한다. 이 이 용어도 처음 알아서 어떻게 구글링해야하는지 한참을 헤맸다.
node-schedule은 컴퓨터 내장 시간에 따라 동작 수행을 가능하게 하는 node.js 기반 스케줄러이다.
node-schedule 외에도
등이 있지만, 가장 다운로드 빈도가 많은 node-schedule을 사용했다.
https://www.npmjs.com/package/node-schedule
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
함수는 첫번째 인자로 시간에 대한 문자열을 받고 두번째 인자로 수행할 콜백함수를 받는다.
- 시간 문자열 사용법
- 각 몇분 마다 , 몇 초 간격도 충분히 구현 가능하다.
//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분 간격으로 현재 시간을 기록해둘 수 있다.
nodemon
이 수정을 파악해 서버를 재시작해버린다!