티스토리 뷰
배경
연동된 외부 재고 관리 시스템에서 주문을 마감하고 쌓인 정보를 가져가는 시각을 "오후 10시로 고정" 에서 "관리자가 시간을 설정할 수 있도록" 바꿔야 하는 요구사항이 있었다.
따라서 이와 같이 관리자가 설정한 스케줄 (주문 마감) 정보를 테이블에 저장하면
매일 새벽 5시 (서버가 제일 한가한 시간) 마다 한번씩 cronjob이 돌면서 해당 날짜에 설정된 스케줄 데이터가 있는지 확인하고
있다면 해당 시각으로 주문 정보 가져가세요~ api 를 요청하는 job을 실행하도록 만들었다.
이때 이 cronjob을 어떤 툴을 이용해서 구현하면 좋을지 고민이었다.
선택 기준
(1) 중복 실행되지 않도록
job은 idempotent 하게 구현해야 하는 원칙이 있어서, 여러번 실행돼도 상관 없게 짜야하지만
많을 때는 pod가 7개씩도 떠있는데, 같은 api요청을 7번 보내는 것은 불필요하므로 최대한 중복 실행되지 않을 도구를 선택
(2) 간단하게 구현할 수 있는 방식
비교
(루비 gem 중에서 선택하기)
1. whenever gem
루비 문법으로 작성한 코드를 리눅스 crontab으로 변환해 실행하는 방식
app container 개수 만큼 중복되어 실행될 것이므로 (1) 번 기준 탈락
2. rufus-scheduler gem
루비 프로세스 내에 스케줄링 스레드를 띄우는 방식
마찬가지 이유로 (1) 번 기준 탈락
3. sidekiq-cron gem
이미 sidekiq을 사용하고 있어서 적용하기 매우 간단하다.
대시보드에서 현황 확인이 가능하다.
sidekiq 프로세스를 띄우면 sidekiq cron poller가 poll_interval 마다 레디스에서 시간이 된 cronjob이 있는지 확인하고 enqueue 해주는 방식.
레디스 sorted sorted-set 자료구조를 사용하여 가장 먼저 요청한 스레드의 job 만 enqueue 하기 때문에 중복 실행되지 않음
(인프라적으로 돌릴 수 있는 방법)
4. k8s cronjob
5. Jenkins
application code랑 연관성이 적은 코드라면 4,5 번 방식도 좋겠지만 cronjob에서 스케줄 테이블을 확인하기 위해 db 연결 같은 추가 작업들이 골치 아파진다
(2) 번 기준 탈락
6. eventbridge schedule
이벤트 소스 → 이벤트 버스 → rule → aws 다른 서비스
이벤트 버스에 모인 이벤트가 대응되는 rule로 라우팅 된다.
rule 타입 두가지 중에서 선택할 수 있다 (1) 이벤트 패턴, (2) 스케줄
스케줄 rule에 타겟으로 lambda를 지정하면, cronjob 처럼 람다를 주기적으로 호출할 수 있다.
근데 역시 lambda에서 active record를 사용할 수 있도록 설정하기가 까다로울거기 때문에.. (아니면 생 sql 쿼리로?? / 돌려야 하는 cronjob이 application 코드와의 연관성이 너무 깊다)
(2) 번 기준에서 별로인 것 같다
7. jets
aws 람다를 사용하고 싶다면 ruby on jets 프레임워크로 작성해서 배포해 보는 것은 어떨까?
'시리즈 > Ruby' 카테고리의 다른 글
omniauth로 rails app에 oauth2 인증 추가하기 (0) | 2023.03.22 |
---|---|
sidekiq으로 job을 batch 묶음으로 실행하기 (0) | 2022.08.05 |
루비 block, lambda, proc (0) | 2022.01.23 |
사이드킥 (0) | 2021.11.12 |
Active Record 연관 데이터 로드 (0) | 2021.10.12 |