쿼츠 중복 해결을 바로 참고하시려면 아래로 이동해주세요!
내가 속한 회사에서 운영하는 플렛폼은 2개의 프로젝트로 운영되고 있다.
A프로젝트에서는 쿼츠를 돌렸을 때 중복 실행이 되지 않아 쿼츠를 실행할 기능들을 모두 A프로젝트에서 구현하고 있었다.
B프로젝트에서 쿼츠를 돌리면 중복 실행이 되어 쿼츠 구현을 하고 있지 않았으나 이번에 나는 B프로젝트의 중복되는 쿼츠 부분을 어떻게든 고치고 싶었다.
오기가 생겼다. 사실 이미 B프로젝트에 작업을 해버렸고, B프로젝트 쿼츠가 안된다고 안 쓸수 없지 않은가....
너무나도 오기가... 생겨서 pc랑 싸울뻔...
일단 한 두달 전쯤에 톰캣 로그에서 쿼츠 스레드가 종료되지 않은채로 남아있다는 로그를 아주 많이 본적이 있었다. 이를 해결하고 싶었지만 당장 어떻게 해결을 해야할지 몰라서 급하게 다른 오류들만 해결하고 쿼츠 스레드 오류는 다음으로 미루었다.
쿼츠 스레드가 종료되지 않았다는 오류는 아래들과 같다.
웹 애플리케이션 [ROOT]이(가) [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1](이)라는 이름의 쓰레드를 시작시킨 것으로 보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:543)
3월 21, 2023 5:43:27 오전 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
경고: 웹 애플리케이션 [ROOT]이(가) [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2](이)라는 이름의 쓰레드를 시작시킨 것으로 보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:543)
3월 21, 2023 5:43:27 오전 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
경고: 웹 애플리케이션 [ROOT]이(가) [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-3](이)라는 이름의 쓰레드를 시작시킨 것으로 보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:543)
3월 21, 2023 5:43:27 오전 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
경고: 웹 애플리케이션 [ROOT]이(가) [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-4](이)라는 이름의 쓰레드를 시작시킨 것으로 보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:543)
3월 21, 2023 5:43:27 오전 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
경고: 웹 애플리케이션 [ROOT]이(가) [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-5](이)라는 이름의 쓰레드를 시작시킨 것으로 보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:543)
3월 21, 2023 5:43:27 오전 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
경고: 웹 애플리케이션 [ROOT]이(가) [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-6](이)라는 이름의 쓰레드를 시작시킨 것으로 보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:543)
3월 21, 2023 5:43:27 오전 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
경고: 웹 애플리케이션 [ROOT]이(가) [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-7](이)라는 이름의 쓰레드를 시작시킨 것으로 보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:543)
3월 21, 2023 5:43:27 오전 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
경고: 웹 애플리케이션 [ROOT]이(가) [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-8](이)라는 이름의 쓰레드를 시작시킨 것으로 보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:543)
3월 21, 2023 5:43:27 오전 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
경고: 웹 애플리케이션 [ROOT]이(가) [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-9](이)라는 이름의 쓰레드를 시작시킨 것으로 보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:543)
3월 21, 2023 5:43:27 오전 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
경고: 웹 애플리케이션 [ROOT]이(가) [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-10](이)라는 이름의 쓰레드를 시작시킨 것으로 보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:543)
이렇게
org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-10
Worker-10까지 쓰레드를 시작시켰고 중지시키지도 못했다고 , 메모리 누수를 유발할 가능성이 있다는 오류였다.
대체 뭐 때문에 중복으로 쿼츠가 돌아가는지 콘솔도 뚫어져라 쳐다보다보니 쿼츠가 처음부터 중복으로 실행되는 것도 아니였다.
그러다 한참..... 쿼츠 중복 실행되는걸로 알아보다가...... 왠걸.. 역시 콘솔 오류 볼 때는 두눈 크게 뜨고 봐야한다....
org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1
org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2
이 두 놈이랑 눈이 마주쳐버린 것.... 잡았다 요놈.........
분명히 쿼츠가 종료되지 않은채로 중복으로 실행이 되고 있었고, 대체 왜 쿼츠가 종료되지도 않았는데..
그래서 또 한참 찾아보다보니 trigger를 실행하는 수를 제한할 수 있는 방법이 있었다.
그 방법이 바로 아래 방법이다 !
보통 Quartz가 작업 스케줄링을 관리하는데 중복 실행을 피하기 위한 내부 메커니즘을 가지고 있다고 한다.
그런데 나는 왜... 중복으로 실행이 되냔 말이다ㅠㅠ,,...
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers" >
<list>
<ref bean="dayTrigger"/>
</list>
</property>
<!-- 여기부터 내가 추가해준 부분 시작 -->
<property name="quartzProperties">
<props>
<!-- 다른 Quartz 속성들 -->
<prop key="org.quartz.threadPool.threadCount">1</prop>
</props>
</property>
<!-- 여기까지 내가 추가해준 부분 끝 -->
</bean>
위와 같이 추가해준 부분을 추가해주면 된다.
간략하게 설명을 덧붙이면, SchedulerFactoryBean은 Quartz 스케줄러를 생성하고 관리하는 데 사용되며, 스케줄러의 실행 스레드 및 스케줄러의 설정을 관리한다.
이를 통해 Quartz의 동작을 커스터마이즈할 수 있다.
property name="" 값은 지정해주면 되며, key="org.quartz.threadPool.threadCount" 값은 정확히 말하자면 중복 실행을 방지하기 위함이 아닌 한번에 trigger를 몇개 실행할지 제한을 두는 카운트이다.
본인같은 경우에는, 1개의 trigger에서 스레드가 종료되기도 전에 동일한 trigger가 동작되었고 앞으로 trigger를 추가하게 되더라도 그렇게 겹치는 시간들에 많은 쿼츠 작업을 할 것 같지는 않아 충분히 특정 시간에 1개의 trigger를 작동시켜도 된다고 판단하였다.
더 많은 도움을 드리지 못했다면,,... 아쉬움을 표합니다 ㅜㅠ.,
'Java' 카테고리의 다른 글
대체 JVM이 무엇이기에 Java를 공부하는 나를 이토록 괴롭히는거니? (0) | 2024.03.12 |
---|---|
[ quartz ] quartz 동일한 trigger 중복 실행 해결 방법, 인스턴스 중복, 인스턴스 2개가 같은 appBase를 바라볼 때. (2) | 2023.06.09 |
[ Spring Boot ] webapp > WEB-INF > views 구조로 JSP 연동, 이미지는 workspace인 webapp 바로 하위에 위치해야 불러 올 수 있다!! (0) | 2023.05.16 |
스프링으로 서비스 구동중 람다 표현식 사용시 오류 이슈 (0) | 2022.07.20 |
[ java ] String to Calendar 적용 가능한 코드 (0) | 2022.07.07 |