무료 서버가 잠드는 문제, 그리고 안 잠들게 하는 방법들
무료로 Node 앱을 올려두면 며칠 뒤 이런 걸 겪게 됩니다. 분명 배포는 됐는데, 오랜만에 주소를 눌러보면 화면이 30초쯤 하얗게 멈춰 있습니다. 새로고침하면 그때부턴 멀쩡합니다.
앱이 죽은 게 아닙니다. 잠들어 있었을 뿐입니다.
슬립이 뭔가
무료 PaaS 대부분은 “요청이 없으면 컨테이너를 내린다”는 정책을 씁니다. 흔히 15분 정도 유휴 상태가 이어지면 컨테이너를 종료하고, 다음 요청이 들어오면 그때 다시 띄웁니다.
무료로 서비스를 제공하려면 어쩔 수 없는 선택입니다. 안 쓰는 앱까지 계속 메모리에 올려두면 원가가 감당이 안 되니까요. 문제는 이게 어떤 앱에는 사소한 불편이고, 어떤 앱에는 기능 자체를 망가뜨린다는 점입니다.
잠들면 안 되는 앱들
깨어날 때까지 기다리면 그만인 앱이라면 슬립은 견딜 만합니다. 포트폴리오 사이트나 가끔 열어보는 대시보드가 그렇죠. 첫 방문자가 30초를 기다린다는 게 아쉽긴 해도, 앱이 하는 일 자체는 그대로입니다.
문제는 이런 앱들입니다.
크론 작업. 매일 새벽 3시에 뭔가를 돌려야 하는데, 그 시각에 앱이 자고 있으면 아무도 깨우지 않습니다. 요청이 와야 깨어나는데, 스케줄러는 요청을 보내는 주체가 아니라 앱 안에 있으니까요. 자는 동안의 스케줄은 그냥 통째로 건너뜁니다.
디스코드 봇 · 텔레그램 봇. 봇은 웹소켓 연결을 유지하면서 이벤트를 받습니다. 컨테이너가 내려가면 연결이 끊기고, HTTP 요청이 들어올 일이 없으니 다시 깨어날 계기도 없습니다. 봇이 조용히 오프라인이 됩니다.
웹훅 수신. 결제 알림이나 GitHub 이벤트를 받는 엔드포인트라면, 첫 요청이 곧 깨우는 요청입니다. 그런데 대부분의 웹훅 발신 측은 타임아웃이 짧습니다. 앱이 깨어나는 데 30초가 걸리면 그 웹훅은 실패로 기록됩니다. 재시도를 해주는 서비스라면 두 번째는 성공하겠지만, 안 해주는 곳도 많습니다.
흔히 쓰는 우회법과 그 결말
검색해보면 “슬립 방지” 방법이 여럿 나옵니다. 대부분 오래 못 갑니다.
자기 자신을 주기적으로 호출하기. 앱 안에서 14분마다 자기 주소로 요청을 보내는 방식입니다. 앱이 이미 자고 있으면 그 코드도 같이 자고 있으므로, 한 번 잠들면 영영 못 깨어납니다. 애초에 잠들지 않게 막는 용도로만 동작하는데, 배포 직후 잠깐이라도 요청이 끊기면 그대로 무너집니다.
외부 모니터링 서비스로 핑 보내기. 5분마다 앱을 찔러주는 무료 모니터링을 걸어두는 방법입니다. 실제로 동작은 합니다. 다만 이건 명시적으로 정책 위반인 경우가 많습니다. 무료 티어의 존재 이유가 “안 쓰는 앱은 내린다”인데, 안 쓰는 앱을 억지로 깨어 있게 만드는 거니까요. 계정이 정지되면 앱과 데이터를 함께 잃습니다.
유료 플랜으로 올리기. 가장 확실한 방법이고, 사실상 정답입니다. 문제는 가격입니다. 해외 PaaS의 가장 싼 유료 플랜은 보통 월 7달러 안팎이라, 환율을 감안하면 만 원이 넘습니다. 취미로 돌리는 봇 하나 때문에 내기엔 부담스러운 금액이죠.
정리하면
슬립은 버그가 아니라 무료의 대가입니다. 우회하려는 시도는 대개 원래 정책과 싸우는 일이라 오래 버티지 못합니다.
그러니 판단 기준은 하나입니다. 내 앱이 요청을 받아야만 의미가 있는가, 아니면 스스로 뭔가를 하고 있어야 의미가 있는가.
전자라면 무료 티어로 충분합니다. 첫 방문자의 30초를 감수하면 되고, 그마저도 트래픽이 꾸준하면 거의 겪지 않습니다.
후자라면 처음부터 잠들지 않는 곳을 찾는 편이 낫습니다. 우회법을 붙였다 떼었다 하면서 봇이 언제 죽었는지 모르고 지내는 시간이, 결국은 더 비쌉니다.