자동매매 봇을 처음 운영하던 시절, 가장 무서운 건 시장 변동성이 아니었습니다. 봇이 언제 조용히 죽어있는지 모른다는 사실이었습니다. 어느 날 아침 눈을 떠보니 BTC가 3시간 동안 롱 포지션을 들고 급락하는 동안 봇은 아무 반응도 하지 않고 있었습니다. VPS 메모리 누수로 프로세스가 조용히 종료된 것이었습니다. 그날 이후 저는 전략보다 인프라를 먼저 챙겨야 한다는 걸 뼈저리게 배웠습니다. 이번 칼럼은 그 경험을 바탕으로, 제가 실제로 구축하고 검증 중인 다운타임 최소화 구조를 공유합니다.
봇이 멈추는 이유는 생각보다 다양하다 — 원인부터 정확히 분류하기
제가 운영 중 겪었거나 커뮤니티에서 수집한 다운타임 원인을 크게 세 가지로 분류합니다. 첫째는 프로세스 레벨 장애입니다. Jesse 프레임워크로 돌리는 봇이 특정 에러를 처리하지 못하고 예외를 뱉으며 종료되는 경우입니다. 특히 바이낸스 API가 일시적으로 429(Rate Limit) 또는 502를 반환할 때, 예외 핸들링 없이 그냥 터지는 코드가 많습니다. 저도 초기에 이 문제로 밤새 봇이 꺼져 있던 적이 있습니다. 둘째는 인프라 레벨 장애입니다. VPS 자체의 메모리 부족, 디스크 풀, 혹은 Cafe24 VPS 기준으로 간헐적으로 발생하는 네트워크 단절이 여기에 해당합니다. 실제로 저는 로그 파일이 수 기가바이트까지 누적되어 디스크가 풀 나면서 봇이 멈추는 상황을 한 번 경험했습니다. 셋째는 외부 의존성 장애입니다. TradingView 웹훅이 전송 실패하거나, 바이낸스 거래소 자체의 점검 혹은 지연이 발생하는 경우입니다. 이 세 가지를 구분하지 않으면 대응 방법이 달라지기 때문에, 다운타임 원인 분류가 인프라 구축의 출발점이라고 생각합니다. 모니터링 없이 운영하는 건, 눈을 감고 운전하는 것과 비슷합니다.
헬스체크 + 자동 재시작 구조 — 제가 실제로 쓰는 설정 방식
현재 제가 운영 중인 구조는 크게 세 층으로 나뉩니다. 첫 번째 층은 systemd 서비스 등록입니다. Jesse 봇을 단순히 터미널에서 python main.py로 실행하는 게 아니라, /etc/systemd/system/jesse-bot.service 파일을 만들어 등록합니다. 핵심 설정은 Restart=always 와 RestartSec=10 입니다. 봇 프로세스가 어떤 이유로든 종료되면 10초 후 자동으로 재시작됩니다. 처음 이 설정을 넣었을 때 의도치 않은 루프 재시작 문제가 생겼는데, StartLimitIntervalSec=60 과 StartLimitBurst=3 을 함께 설정해서 60초 안에 3번 이상 재시작되면 멈추도록 안전장치를 달았습니다. 두 번째 층은 Flask 기반 헬스체크 API입니다. 봇 프로세스 안에 별도 스레드로 간단한 Flask 서버를 띄워 GET /health 요청에 200을 반환하도록 만들었습니다. 세 번째 층은 외부 핑 모니터링입니다. UptimeRobot 무료 플랜을 사용해 5분마다 해당 엔드포인트를 체크하고, 응답이 없으면 텔레그램으로 즉시 알림을 받습니다. 이 세 층이 맞물리면, 봇이 죽더라도 10초 안에 재시작되고, 재시작이 안 되면 5분 이내로 제가 알림을 받는 구조가 됩니다. 완벽하진 않지만 1인 운영 기준으로는 현재까지 가장 실용적인 조합이라고 보고 있습니다.
로그 관리와 디스크 용량 — 조용한 봇 킬러를 막는 방법
헬스체크와 자동 재시작을 구축하고 나서 한동안 안심했는데, 예상 밖의 복병이 있었습니다. 바로 로그 파일 누적입니다. Jesse 프레임워크는 기본적으로 상세한 로그를 남기고, 다중 코인 페어를 동시에 운영하다 보면 하루에도 수십 MB씩 로그가 쌓입니다. 저는 한 달쯤 지난 시점에 df -h 명령어로 디스크 상태를 확인했다가 루트 파티션이 94% 채워진 걸 발견했습니다. 그 상태가 조금만 더 지속됐다면 봇이 로그 파일에 쓰기를 실패하면서 예외를 뱉고 종료됐을 겁니다. 해결책은 두 가지였습니다. 첫째로 logrotate 설정을 추가했습니다. /etc/logrotate.d/ 경로에 jesse 전용 설정 파일을 만들어 매일 로테이션하고, 7일치만 보관하도록 했습니다. compress 옵션을 추가해 오래된 로그는 gzip으로 압축해서 공간을 절약합니다. 둘째로 cron 잡으로 주간 디스크 리포트를 텔레그램에 보내도록 했습니다. 매주 일요일 오전 9시에 df -h 출력을 파싱해서 사용률이 80%를 넘으면 경고 메시지를 보내는 간단한 bash 스크립트입니다. 이 두 가지를 적용한 후로 디스크 관련 장애는 없었습니다. 인프라는 처음 설정하고 잊어버리는 게 아니라, 주기적으로 상태를 확인하는 루틴이 같이 있어야 한다는 걸 이 경험으로 배웠습니다.
💬 운영자 한마디
저는 자동매매 운영을 ‘전략 70%, 인프라 30%’로 시작했다가 지금은 ‘전략 50%, 인프라 50%’로 비중을 조정했습니다. 봇이 살아있어야 전략이 의미가 있기 때문입니다. 아직 모든 장애 시나리오를 다 막은 건 아니고, 여전히 관찰하고 개선 중입니다. 하지만 헬스체크 하나를 추가한 것만으로도 심리적 안정감이 크게 달라졌습니다.
— J_River · autoprofit 운영자
✅ 이번 주 체크리스트
- Jesse 봇을 systemd 서비스로 등록하고 Restart=always 설정 확인
- StartLimitBurst=3 으로 무한 재시작 루프 방지 안전장치 추가
- 봇 내부에 Flask /health 엔드포인트 스레드로 별도 실행
- UptimeRobot 무료 플랜으로 5분 주기 외부 헬스체크 및 텔레그램 알림 연결
- logrotate 설정으로 로그 파일 7일치만 보관하고 자동 압축
- cron 잡으로 매주 디스크 사용률 80% 초과 시 텔레그램 경고 발송
- df -h 및 free -h 명령어로 주 1회 수동 서버 상태 점검 루틴 유지
다운타임 최소화는 완성이 아니라 지속적인 개선의 영역입니다. 지금 운영 중이라면 오늘 당장 df -h 한 번만 쳐보세요. 디스크 상태가 어떤지 확인하는 것, 그게 인프라 관리의 첫걸음입니다.
※ 본 콘텐츠는 운영자 개인의 경험과 연구를 바탕으로 한 정보 제공 목적이며, 특정 종목에 대한 투자 권유나 매매 시그널이 아닙니다. 암호화폐 및 자동매매는 원금 손실 가능성이 있는 고위험 활동이며, 모든 투자 판단과 그 결과에 대한 책임은 투자자 본인에게 있습니다.