크론 잡(Cron job)은 서버 관리나 작업을 자동화하는 데 많이 사용되는 방법 중 하나입니다. 예시를 들어보면 정기적으로 데이터베이스 백업을 수행하거나 문제가 되는 데이터를 정리하고, 이메일 알림을 발송하는 등 다양한 용도로 사용됩니다.
하지만 크론 작업을 무겁고 중요하게 사용할 경우 문제점이 하나 발생할 수 있는데요. 바로 모니터링이 쉽지 않다는 점입니다. 크론이 정상적으로 실행되고 종료되었는지, 오류가 발생하지 않았는지 혹시 중간에 배포가 있어서 끊기지 않았는지 확인하는 작업은 수동적이고 번거로울 수 있습니다. 개인의 퍼포먼스에 의존하는 만큼 관리하는 사람이 부재 중일 때, 문제가 발생한다면 꽤나 오래 문제가 지속될 수도 있습니다.
저 또한 비슷한 문제를 겪었습니다. 로직의 누락으로 크론이 실행 조차 되지 않았던 상황인데요.
크론의 정상 동작 여부는 동작 이후 에러 모니터링에 에러 알람이 뜨는가, 즉 동작이 실패했는지를 추적하여 크론의 흐름을 추적하고 있었는데요. 시작조차 못하니 당연히 에러도 뜨지 않았을 것이고, 위 방법으로 돌지 않았음을 추적하는 것도 불가능했습니다.
이 문제를 크게 맞고 느낀 점은 크론의 실패가 아닌 정상 동작을 추적할 수 있는 무언가가 필요하다였습니다. 그런데, 크론이라는 특성 상 이를 추적하기는 쉽지 않습니다. 예를 들어서 매일 n시에 동작하는 크론 잡을 추적하기 위해서는 무엇이 필요할까요? 크론 잡을 추적하는 크론 잡을 띄워야 할까요? 실패한 크론을 다시 돌릴 수 있도록 플랫폼을 깔아야 할까요? 물론 이런 방법들을 통하여 더 근본적으로 해결할 수는 있겠으나, 이런 플랫폼을 까는 일은 손이 꽤나 많이 가는 일입니다. 그래서 저는 이를 Sentry의 Cron monitoring 기능을 사용하여 이 문제를 우선적으로 해결했습니다.
Sentry Cron Monitoring
모니터링을 위한 Sentry 환경이 구축되어있다면 5분 만에 세팅이 가능한데요.
위와 같이 타겟으로 할 sentry project를 설정하고, 기대되는 cron schedule을 설정할 수 있습니다. schedule은 crontab과 Interval 두 가지 방식으로 설정할 수 있습니다.
다음으로 동작에 대한 마진을 지정합니다. Grace Period는 지정한 시간에서 n분 내에 동작을 시작하면 에러로 보지 않겠다는 설정이고, Max Runtime은 동작 시작 이후 n분 내에 종료되지 않으면 에러로 간주하겠다는 설정입니다.
아래에서 설명하겠지만, 크론 잡이 언제 시작해서 얼마나 걸렸는지에 대한 정보를 쌓아서 제공하니, 이 데이터를 쌓아가며 가능한 민감하게 설정하시는 것을 추천드립니다.
여기까지 확인하셨으면 모니터의 생성은 거의 완료되었습니다.
마지막으로 생성된 모니터의 수정화면으로 들어옵니다. 들어와보면 생성 시에는 보이지 않았던 monitor-slug라는 값을 보실 수 있는데요. 이 값이 어플리케이션에서 모니터를 구별하는 id와 같은 값입니다. 충분히 식별할 수 있는 값으로 설정해 줍니다.
저는 [어플리케이션 이름]-[크론 이름]으로 설정하여 어디서 도는 어떤 크론인지 알 수 있도록 세팅했습니다.
어플리케이션 세팅은 이 셋업 문서를 참고하셔서 세팅하시면 됩니다. 위에서 설정한 slug만 주의하여 세팅하시면 됩니다.
활용 예시
아래와 같이 예정된 시간에 크론 잡이 수행되었는지 그리고 얼마나 걸렸는지 등의 지표를 볼 수 있습니다.
그리고 위 이미지를 보면 Failed가 하나 있는 것을 볼 수 있는데요. 이를 Alert을 설정하여 모니터링할 수 있습니다.
위에서 설정한 slug는 event tag의 monitor.slug로 나오게 되는데요. 해당 slug 값에 대한 filter를 통하여 cron monitoring alert을 만들 수 있습니다. cron monitor마다 alert 설정을 생성하는 것은 꽤나 귀찮은 일이니, 어플리케이션 별로 사용할 slug prefix를 정하고 starts with 조건으로 filter하시는 것을 추천드립니다.
슬랙 알림을 설정하면 아래와 같이 메세지가 오는 것을 받아보실 수 있습니다.
문제점
종종 잘 돌았는데, 안 돌았다고 알림을 줍니다. 간단한 공수로 붙일 수 있으므로 그 정도 문제는 감내할 수 있다고 판단했습니다. beta니까,,,
다른 환경에서 세팅하시는 분들은 무시해도 되나, spring 환경이라면 봐주셔야 하는 내용도 있습니다.
sentry spring boot 라이브러리를 이용하여 세팅하는 경우에는 sentry cron monitoring을 위한 로직들이 bean으로 등록되는데요. 이 bean을 등록하는 configuration에 @ConditionalOnClass(ProceedingJoinPoint.class)가 걸려있습니다. 그리고 ProceedingJoinPoint은 aspectj 의존성을 통하여 들어오는데, sentry spring에는 aspectj 의존성이 없습니다. 그래서 어플리케이션 레벨에서 따로 aspectj-weaver를 넣어줘야 동작하는 문제가 있었습니다.
이슈는 발급해뒀는데, 언제 해결될진,,, 모르겠군요 ㅜㅜ
'Java & Kolin' 카테고리의 다른 글
M1 사용기 - JVM환경에서 ARM / Rosetta 번역 알아내기 (0) | 2021.10.10 |
---|---|
Garbage Collection (0) | 2021.04.04 |
JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가. (0) | 2021.03.30 |
Kotlin의 Generic - 기본문법 (0) | 2021.03.03 |
Spring 오류 / The signing key's size is 240 bits which is not secure enough for the HS256 algorithm. (0) | 2021.02.12 |
댓글