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