BE/Spring-Boot

[SpringBoot] 스케줄러(@Scheduled)가 간헐적으로 동작 안하는 문제

suhyeon chae 2024. 5. 7. 14:21
문제 발생

 

필요한 기능 : 특정 시간(오전 6시)에 외부 API를 호출하여 DB에 Insert

문제점 : 오전 6시에 해당 스케줄러가 실행이 되어야 하는데, 출근해서 해당 Table을 확인하니 스케줄러가 동작 안하여 Insert가 안되어 있음

 

더 심각한건.. 도대체 어느 조건에서 왜? 실행이 안되는건지 모른다는 점이다...  로컬에서 실행하면 매우 잘 되는데 배포만 하면 잘 안된다는 문제만 파악하였다..

 

검색을 해도 Timezone 이라는 말뿐......

계속 검색해도 타임존 문제라고만 나왔다.  근데 그냥 뭔가 단순히 생각했을때 타임존 문제라면 그냥 그 시간이 되었을 때 동작을 해야하는데 아예 실행이 안됐으니 타임존 문제라는 것이 너무 이해가 안되었다.

 

해결 과정 - 로그 확인

로컬로 스프링 프로젝트를 시작시켰을 때 터미널에 나오는 시간은 현재 시각과 같았다. 

하지만, 배포되어 있는 스프링 서버의 로그를 확인했을 때 현재 시간과 다르다는 것을 확인했다. 

 

로컬에서는 오전 9시 2분인데 ec2 상의 도커로 배포되어 있는 스프링 서버는 오전 12였다..  (타임존 문제 일단 확인)

 

해결 - 타임존 설정

도커로 배포를 했기 때문에 실행명령어를 작성하는 Dockerfile에서 서버 실행 명령어를 적는 부분(ENTRYPOINT) 부분에 timezone을 설정하는 옵션을 넣어준다.)

* 타임존 설정하는 부분을 application.yml에 넣어도 된다는 말이 있었는데 따라했을때 잘 안되었다.

 

FROM openjdk:17-jdk-slim

WORKDIR /workspace

ARG JAR_FILE_PATH=build/libs/*.jar

COPY ${JAR_FILE_PATH} app.jar

EXPOSE 8080

# 타임존을 Asia/Seoul로 설정
ENV TZ=Asia/Seoul

# 타임존을 환경 변수로 설정하여 JVM 옵션으로 전달합니다.
ENTRYPOINT ["java", "-Dspring.profiles.active=prod", "-Duser.timezone=${TZ}", "-jar", "app.jar"]

 

 

결론
- 타임존 설정만 진행하고 실제 시간과 맞는지 확인을 먼저 진행했다. 
- 시간 설정 후 특정 시간에 스케줄러가 잘 동작하는지 확인도 진행했다.
- 매우 잘됨.............
- 스케줄러가 동작하지 않을때 제일 먼저 타임존을 의심해보자!!! 다들 왜 타임존 얘기만 하셨는지 알 것같다.. 진짜 타임존 문제였다...