1. 문제 발견
회사에서 로그를 확인하던 중 자바 스케줄러가 중복 호출되고 있는 것을 발견했다.
매일 새벽, 정해진 시간에 인사정보를 최신화시켜 주는 프로시저이다.
이 외에도 많은 프로시저들이 자바 스케줄러에 의해 중복 호출되고 있던 것이다.
중복 호출이 되고 있었지만 사용하는 데 전혀 문제가 없었기 때문에 지금까지 아무렇지 않게 넘어갔던 것 같다.
물론, B2B 서비스였기 때문에 새벽에는 사용량이 없어서 문제 되지 않겠지만, 이슈를 발견한 이상 모른 체 넘어갈 수 없었다.
2. 원인
톰캣 공식 문서에 아래와 같은 내용이 적혀 있다.
💡 내용을 요약해 보면 다음과 같다.
1. 자동 배포를 true로 설정했을 때, docBase를 정의할 경우 appBase 외부에 있어야 한다.
2. 명시적으로 정의할 경우 자동 배포를 끄거나, deployIgnore 기능을 설정해 주어야 한다.
그렇지 않으면, 애플리케이션이 중복 배포되어 문제가 될 수 있다.
(회사 소스코드이므로 문제 되지 않도록 지금부터 명칭을 app이라고 추상화해서 부르기로 하겠다)
참고로 서비스 구조는 webapps 상위 디렉터리에 하위로 app이 있는 구조이고, tomcat 8.0을 사용하고 있다.
server.xml을 보면 docBase로 app을 정의했지만 appBase에 app의 상위 디렉터리까지 함께 정의했으며
autoDeploy를 true로 설정하고 있었다.
정확히 톰캣 공식 문서에서 언급한 내용에 위배되고 있었다.
3. 해결 방법
내가 찾은 해결 방법은 3가지가 있다.
1) appBase를 지우고 docBase에 배포할 서비스 절대 경로를 지정한다.
2) 공식 문서 요약 1번처럼 appBase에 정의한 디렉터리 외부로 app을 옮기고 정의하기.
3) appBase의 자동 배포 기능을 끈다.
여러 방법 중 나는 3번 방법을 적용하기로 결정했다.
이유는 간단하다.
서비스 디렉터리의 경로가 변경될 수 있는 만약의 상황도 고려를 해야 한다고 생각했고, 자연스럽게 1~2번은 제거되었다.
(server.xml이 경로 변경에 의존하지 않아야 한다)
4. 테스트
4-1. 테스트 세팅
먼저 xml 파일에 schedulerFactoryBean, testServiceTrigger, testService bean을 등록해 주었고,
10초마다 서비스를 호출하도록 cron을 세팅해 주었다.
그리고 testService가 호출되었을 때 확인을 위해 log를 찍어두었다.
4-2. server.xml 수정 전
기존처럼 server.xml을 수정하지 않고 자동 배포 기능을 true로 설정했을 때 먼저 확인해 보았다.
18:12:00초부터 10초마다 서비스가 한 번씩 호출되다가
18:12:50초부터 중복 배포되어 서비스가 두 번씩 중복 호출되는 것을 확인할 수 있다.
4-3. server.xml 수정 후
자동 배포가 되지 않도록 autoDeploy와 deployOnStartup 속성을 false로 설정하였다.
18:20:40초부터 10초마다 서비스가 호출되었고 시간이 지나도 서비스는 한 번씩만 호출되는 것을 확인할 수 있다.
'Language > Java' 카테고리의 다른 글
[Java] 생성자란? (0) | 2021.10.31 |
---|---|
[Java] 자바 컬렉션(Collection)이란? (2) | 2021.09.09 |
[Java] this 키워드의 개념과 사용 방법 세 가지 (0) | 2021.09.08 |
[Java] 함수 호출 'CallByValue' 와 'CallByReference' 의 차이 (0) | 2021.09.03 |
[Java] JVM Architecture (ClassLoader, Runtime Data Areas, Execution Engine) 정리 (0) | 2021.08.31 |
댓글