cron서버 환경 구성 삽질 일지

June
None
Published in
7 min readJun 27, 2023

--

이미지 출처: https://edge.id/article/what-is-a-web-server-understanding-functions-and-types/

안녕하세요. 휴먼스케이프 june입니다.

오늘은 Django 기반의 서비스에서 크론 서버를 구성하는 과정에 대해 공유하려고 합니다. 이 글에서는 크론 서버 구성을 위해 우리가 겪었던 어려움과 선택한 해결책에 대해 설명하려 합니다.

크론 서버 구성

우리는 임상 연구를 적재하는 서비스를 개발하고 있었습니다. 처음에는 크론 서버 없이 필요할 때마다 API를 호출하여 임상 연구를 적재하는 방식으로 작업을 수행했습니다. 그러나 추가 리소스를 투입하지 않고도 주기적으로 임상 연구를 적재하기 위해 크론 서비스를 도입하게 되었습니다.

우리는 크게 2가지의 옵션을 두고 고려했습니다.

  1. aws에서 제공하는 크론 관련 서비스 사용
  2. Django에서 크론 작업을 관리하기 위해 django-crontab을 사용하고, EC2를 사용하여 관리

(Api 서버에 크론을 추가하지 않고 크론서버를 따로 만드는 이유는 이후 auto scaling시 같은 크론 작업이 두번 돌아갈 수 있기 때문입니다.)

첫 번째 옵션인 AWS의 크론 관련 서비스는 AWS 콘솔을 통해 동작 상황을 쉽게 파악할 수 있으며, AWS에서 제공하는 다양한 옵션을 통해 확장성을 기대할 수 있었습니다. 하지만 관리 포인트가 증가하고 코드로 크론을 관리할 수 없는 단점이 있었습니다.

두 번째 옵션인 Django와 django-crontab을 사용하여 EC2에 크론 작업을 관리하는 방법은 구조가 직관적이고 코드로 크론을 관리할 수 있는 장점이 있었습니다.

우리는 고민 끝에 두 번째 옵션을 선택하여 Django 서비스를 EC2에 배포하고, django-crontab 패키지를 사용하여 크론 작업을 관리하기로 결정했습니다.

django-crontab을 통한 cronjob 관리

크론은 크게 크론 데몬과 크론 테이블로 구성됩니다. 크론 데몬은 운영체제에서 동작하는 백그라운드 프로세스로, 정해진 시간에 크론 테이블에 등록된 작업을 실행합니다. 크론 테이블은 크론 작업의 목록을 관리하는 데이터베이스나 텍스트 파일로, 각 작업의 실행 주기와 명령어 등을 포함합니다.

django-crontab 패키지를 사용하면 Django 애플리케이션 내에서 크론 작업을 등록할 수 있습니다. 먼저, settings.py 파일에서 크론 작업을 등록할 수 있는 크론 설정(CRONJOBS)을 추가해야 합니다. 이 설정은 크론 작업의 주기와 실행할 함수 또는 커맨드를 지정합니다.

예를 들어, 매일 오전 3시에 실행되는 크론 작업을 등록하고 싶다면, settings.py 파일에 다음과 같은 내용을 추가합니다

CRONJOBS = [
('0 3 * * *', 'myapp.cron.my_cron_job')
]

위의 예시에서 '0 3 * * *'는 크론 표현식으로, 매일 오전 3시에 실행됨을 나타냅니다. 'myapp.cron.my_cron_job'은 실행할 함수의 경로를 나타내며, 이는 실제로 실행될 크론 작업 함수를 가리킵니다.

우리는 테스트의 용이성을 위해 작업들을 django command로 만든 후, command를 호출하는 함수를 CRONJOBS로 등록했습니다.

django-crontab 패키지를 사용하면 Django 애플리케이션과 크론 작업을 함께 버전 관리할 수 있습니다. 크론 작업을 Django 프로젝트 내에서 관리하면 코드베이스의 일부로서 크론 작업을 유지하고, 배포 및 관리가 편리해집니다. 또한, Django의 ORM과 다른 기능들을 크론 작업 내에서 활용할 수 있어 개발과 유지보수가 용이해집니다.

이와 같은 방식으로 Django 애플리케이션과 크론 작업을 통합하면, 크론 작업을 실행해야 할 시간과 주기를 Django 설정 파일에서 관리할 수 있으며, Django 애플리케이션의 다른 부분과 일관된 방식으로 크론 작업을 개발하고 관리할 수 있습니다.

Slack Webhook 도입

우리는 크론 서버의 상태를 실시간으로 모니터링하고, 잠재적인 문제를 빠르게 감지하기 위해 Slack webhook을 도입했습니다.

webhook은 크론 작업이 실행될 때마다 성공 여부를 확인하는 메시지를 전송하는 방식으로 개발하였습니다.

Slack의 경우 API 제공이 원활하고, 사내 메신저로 사용중이기 때문에 접근성이 좋아 사용하기로 했습니다.

예기치 않은 상황으로 인 크론 서버가 다운되는 경우, Slack webhook을 통한 이슈 전달이 불가능할 수도 있습니다. 이를 고려하여 우리는 크론 작업이 실행될 때마다 성공 여부를 확인하는 메시지를 전송하는 방식으로 개발하였습니다.

이를 통해 우리의 시스템은 안정성을 유지하며, 개발자들은 크론 서버의 동작 상태에 대해 쉽고 편리하게 알 수 있게 되었습니다.

크론서버 docker 도입

그러나 문제가 발생했습니다. 배포할 때마다 EC2 환경이 조금씩 달라져서 배포에 실패하는 경우가 발생했습니다. 이 문제를 해결하기 위해 우리는 Docker를 도입하기로 결정했습니다. Docker를 사용하여 항상 동일한 서버 환경을 제공하여 환경 구성과 관련된 문제 및 변수를 제거하고자 했습니다.

우리는 Docker를 사용할 수 있는 여러 서비스를 조사했습니다. 크게 네 가지 옵션이 있었습니다.

  1. 기존 EC2에 Docker를 설치하여 사용하는 방법
  2. AWS Batch 사용
  3. Beanstalk Worker 사용
  4. ECS 사용

우리는 인프라 의존성을 줄이고자 코드로 가능한 많은 부분을 관리하려고 했으며, 실제로 동작하는 크론 작업은 Django admin을 통해 모두 파악할 수 있었기 때문에 AWS 콘솔을 통해 현황을 파악하는 일이 거의 없었습니다. 따라서 우리는 해야 할 작업이 적고 러닝 커브가 낮은 EC2를 선택했습니다. 도커 이미지는 AWS ECR을 통해 관리하기로 결정했습니다.

Docker를 사용할 수 있는 여러 서비스를 조사하며 알아낸 장단점은 다음과 같습니다.

  • EC2에 Docker를 설치하여 사용하는 방법은 EC2를 재생성해야 할 경우 Codedeploy 서비스와 연결하고, Docker를 설치하기 위해 SSH로 서버에 접근하여 작업해야 하는 단점이 있었습니다. 그러나 자유도가 높고 이전에 EC2를 사용하고 있었기 때문에 작업량이 적은 장점이 있었습니다.
  • AWS Batch는 작업 당 작업 정의를 통해 세밀한 옵션 조정이 가능하며, 작업 현황을 쉽게 파악할 수 있는 장점이 있었습니다. 그러나 세밀한 옵션 조정이 필요하지 않은 경우 오히려 단점이 될 수 있었고, 우리는 이미 각 데이터의 처리 상태를 관리하기 위해 control_status_type이라는 컬럼을 사용하고 있었기 때문에 작업 현황 파악 기능이 필요하지 않았습니다.
  • Beanstalk Worker는 EC2와 Batch 사이에 위치한 서비스로 보입니다. 세밀한 옵션 조정이 가능하지만 원하지 않는 경우에는 기본 옵션으로 작업을 진행할 수 있었으며, 이미 API 서버를 Beanstalk를 통해 서비스하고 있어 한꺼번에 관리하기 편리했습니다. 그러나 Beanstalk Worker를 사용하기 위해서는 기존에 커맨드로 만들어 둔 크론 작업을 API로 변환해야 하는 작업이 필요했습니다.
  • ECS는 AWS Batch와 유사한 방식으로 사용되는 것으로 보였습니다.

회고

위에서 서술한 여러 작업을 진행한 후 스스로에 대한 회고를 간단하게 진행해 보았습니다.

아쉬운점은 다음과 같습니다.

  • 위에서 서술한 ec2의 단점을 상쇄할만한 방법을 찾지 않고 작업을 마무리 한 점이 아쉬웠습니다. 현재는 ec2 인스턴스 개설 후 작성해야 하는 명령어 모음을 메모해두고 복붙하는 형태로 사용중입니다.
  • slack webhook이 주기적으로 계속 날아오기 때문에 매번 확인해야 하는 작업자 입장에서 피로감이 생기게 됩니다. slack webhook이 정해진 시간내에 오지 않을 경우에만 알려주는 다른 서비스를 접목시켰으면 어땠을까 하는 생각이 있습니다.

잘한점은 다음과 같습니다.

  • 인프라 의존성을 줄이고자 시도했고, 스타트업의 경우 크레딧을 얻어 클라우드 플랫폼을 옮기는 경우가 종종 있어 이 경우에 매우 유용했습니다.
  • 남들이 많이 사용하는 서비스를 이용해 그냥 개발하기 보다 현재 상황을 정확히 파악하고, 상황에 맞는 구현방법을 찾아 오버/언더 엔지니어링을 피하고자 했습니다.

지금까지 Django 기반의 크론 서버 환경 구성에 대해 알아보았습니다. 다음 글에서는 도커 이미지 관리에 대해 자세히 다루도록 하겠습니다. 감사합니다!

--

--