다니고 있는 직장에서 CRON 스케줄러를 사용해야 하는 일이 생겼다.
내가 담당하고 있는 사이트 중 메인 페이지에 정기간행물 정보를 노출하는 사이트가 있었는데, '어떠한' 기능 때문에 사이트 최초 접속 시 로딩 시간이 매우 길다는 이슈가 발견됐기 때문이다.
여기에
간행물 개수도 기존에 운영 중이던 7개에서 무려 4개나 늘려 총 11개를 노출해야 했으므로, 대대적인 개편 작업이 필요하게 되었다. (ㅠㅠ 분명 수정 작업이라매요)
해당 사이트의 '어떠한' 기능은 내가 여기에 입사하고 두 달쯤 된 완전 신입 개발자일 때 실무는 이런 곳이구나 ㅠㅠ 하며 피똥 싸며 개발한 기능이었다.
말만 기능이지 사실상 서비스단, 쿼리, JSTL 등 곳곳에 야무지게 삽질한 것의.. 산물이었다.
AS-IS 시스템은 아래와 같다.
1. 출력해야 하는 간행물의 종류는 총 7개이며 '전체' 탭을 포함하여 총 8개의 버튼이 메인 페이지에 노출된다.
2. 메인 페이지 로딩 시 모든 간행물 정보를 서비스단에서 리스트 객체에 담아 넘겨주고 해당 객체를 JSP에서 가공하여 출력한다.
※ 각각의 탭에는 해당하는 간행물을 14개씩 출력하고 슬라이드 기능을 사용하여 7개씩 2페이지로 출력하고, 전체 간행물 탭에는 7개 간행물의 가장 최신 간행물 1건씩만 가져와서 출력한다.
메인 페이지 로딩 시간이 오래 걸린 이유 중 가장 큰 문제점은
간행물 정보들을 메인페이지 로딩 시 조회했는데, 조회하는 간행물마다 서비스 로직이 따로 붙어있었다.
이게 무슨 말이냐면
간행물이 1번부터 7번까지 있는데 1번 간행물 조회 시 조회 로직 1회 실행, 2번 간행물 조회 시 조회 로직 1회 실행, 3번 간행물 조회 시 조회 로직 1회 실행... 이런 방식으로 7개의 간행물을 7번 조회하여 메인에 뿌려왔었고, 앞으로는 11개의 간행물을 위와 같은 방식으로 출력해야 했는데 생각만 해도 아찔했다.
최초 작업~개편 작업 당시까지도 나는 스케줄러의 존재를 모르고 있었다. 그래서 현재 상태를 유지하되 중복된 소스들은 제거하고 서비스단 로직은 리팩토링을 진행하며 로딩 시간을 최소화하기 위해 열을 올리고 있었다.
그러던 중 팀장님께서 스케줄러를 사용해보는 게 어떻겠냐고 권유해주셨는데, 속도와 작업시간도 그렇고, 추후 유지보수 편의성을 고려해봤을 때 쓰지 않을 이유가 없어서 스케줄러로 작업하겠다고 했었다.
서론이 매우 매우 길었는데, 사용법은 매우 간단하다!
1. 스케줄러 xml 파일을 추가한다.
(제가 작업한 프로젝트의 XML File Type은 MyBatis Spring XML Config인데, 프로젝트마다 설정 파일이나, 선언 방식이 다를 수 있으니 참고 부탁드립니다.)
2. 추가한 xml 파일에 다음과 같이 추가한다.
<context:component-scan base-package="com.example.패키지위치" />
<!-- '패키지위치'에는 실제 사용하는 패키지 경로를 집어넣어야 함 -->
<task:scheduler id="scheduler" pool-size="10" />
<task:annotation-driven scheduler="scheduler" />
3. @Scheduled 어노테이션으로 Cron 세팅
package com.example.패키지위치;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ExampleClass {
@Scheduled(cron="0/10 * * * * *")
public void schedulerTest() throws Exception {
try {
System.out.println("로그 확인");
} catch(ExampleException e) {
// 예외 발생 시
}
}
}
/*
소스는 반출이 불가하여 ㅠㅠ.. 최대한 간략하게 옴겨 적었습니다.
해당 소스를 그대로 사용하지마시고 구조만 확인하셔도 됩니다.
그만큼 쉽습니다!
*/
쓰고 나니 진...짜 별 거 없는데 위와 같이 스케줄러 로직을 준비하고 커스터마이징만 하면 된다.
스케줄러 작동 시간을 설정하는 표현식은 아래와 같다.
4. 표현식
※ 아래는 표현식을 만들 때 참고할 수 있는 웹 사이트다.
CronMaker
www.cronmaker.com
사이트에 접속하여 분, 시간, 일, 주, 월 별로 선택하여 Generate 하면 설정한 시간대로 표현식이 출력되는데 그걸 그대로 가져다 써도 된다.
TO-BE
1. 간행물들의 정보는 CRON 스케줄러를 이용하여 매일 새벽 1시 정각에 수집하며, 수집된 정보는 서버에 JSON 파일로 저장한다.
2. 저장한 JSON 파일을 메인 페이지에 import 하고, 자바스크립트로 가공하여 출력한다.
어쨌든 나는 간행물 정보를 하루에 한 번, 새벽 시간대에 실행되도록 설정해놓았고, 며칠 동안 스케줄러가 정상적으로 동작하는지 모니터링을 진행하였다.
파싱 로그와 JSON 파일의 내용도 정상적으로 수정되고 있었기 때문에 작업한 모든 파일을 반영하고 작업을 마무리하였다.
기존에 존재하던 불필요한 JSTL, 쿼리 및 로직 등을 걷어내니 아주 속이 시원했다. 작업 이후 약 1년 가까이 지난 거 같은데 아직까지도 말이 없는 걸로 봐서는 그래도.. 올려놓을 만 한가보다 ㅋㅅㅋ
끝!
참고 링크
cron - Wikipedia
From Wikipedia, the free encyclopedia Jump to navigation Jump to search Job scheduler for Unix-like operating systems The cron command-line utility, also known as cron job,[1][2] is a job scheduler on Unix-like operating systems. Users who set up and maint
en.wikipedia.org
'BackEnd > Spring Framework' 카테고리의 다른 글
[Spring] Java 스프링 프레임워크 이클립스에서 JUnit 테스트 환경 만들고 테스트하기 (0) | 2020.08.08 |
---|---|
[Spring] Java 스프링 프레임워크 이클립스에서 Legacy Project 만들기 (0) | 2020.08.08 |
[Spring] Java 스프링 프레임워크 이클립스에서 프로젝트 만들기 (0) | 2020.08.08 |
[Spring] Java 스프링 프레임워크의 트랜잭션 관리 (0) | 2020.08.08 |
[Spring] Java 스프링 프레임워크 의존성 주입 (0) | 2020.08.07 |