CODEOK.NET

Page history of 서버 프로세스를 관리하는 올바른 방법



Title: 서버 프로세스 띄우기 | edited by Youngrok Pak at 5 years, 8 months ago.

웹사이트 개발을 완료하고 서비스할 프로덕션(production) 서버에 배치(deploy)할 때 고민하게 되는 문제 중 하나가 서버에서 띄워야 하는 여러 가지 프로세스들을 어떻게 띄울 것인가 하는 문제다. 프로세스가 죽으면 다시 띄우는 것도 물론 필요하다. monit이나 supervisord, god 등은 이런 목적으로 나온 것이다(몇 가지 부가적인 목적이 더 있긴 하다). 하지만 이건 OS에 대한 이해 부족에서 나온 것이다. 프로세스 관리는 OS의 핵심적인 기반이 되는 기능이다. 본 연구에서는 왜 monit 등이 잘못된 선택인지, 올바른 방법은 무엇인지에 대해 다룰 것이다.

프로세스 No. 1 Init

올바른 방법은 OS의 init 시스템, 혹은 그와 유사한 대안 시스템을 사용하는 것이다. init은 유닉스에서 부팅될 때 첫번째로 만들어지는 프로세스다. 그래서 프로세스 번호가 1이고, 이후의 모든 프로세스는 init 프로세스의 자손이 되고, 시스템이 부팅될 때 뜨는 모든 프로세스는 init이 띄우게 된다. respawn이 설정된 프로세스는 죽었을 때 다시 띄우는 역할도 한다. 그러니 서버에 프로세스를 띄워야 한다면 init에 맡기는 것이 자연스럽지 않겠는가.

물론 init 시스템은 낡고 문제점이 있고, 그건 부팅 과정의 문제점이 크고, 프로세스를 관리하는 데는 별 문제가 없다. 다만, 조금 번거롭긴 하다. 사용법은 Managing Linux daemons with init scripts를 참조하라. 보면 알겠지만 좀 귀찮다.

하지만, 이제 이 init 시스템은 역사 속으로 사라질 예정이다. 아니, 많은 리눅스 배포판에서 이미 사라졌다. 우분투는 이미 수년 전 init을 upstart로 대체했고, 다른 배포판들은 systemd로 방향을 잡았으며 최근에 우분투도 systemd에 합류하기로 했다. 그러니까, 미래는 systemd에 있고, 서버에서 프로세스를 띄우고 관리해야 한다면 systemd를 쓰는 게 정답이다.

monit에서 시작된 흑역사

그런데 왜 init이 있는데 monit 같은 툴들이 등장했을까? 여기에는 약간의 역사가 있다. 수년 전, Ruby on Rails 개발자들 사이에서 monit이 유행을 타기 시작했다. Rails가 뜨기 전까지 웹 개발의 주류는 PHP와 자바였는데, PHP는 아파치에 모듈로 붙으니 따로 프로세스 관리를 할 필요가 없고, 자바 WAS들은 자체적인 프로세스 관리를 탑재했었다. 그러다보니 아마도 웹 개발자가 서버의 프로세스를 어떻게 띄우고 내리고 리스타트시키는지에 대해 고민할 기회가 별로 없었을 것이다. 당시 웹 개발의 시대를 이끈 것은 그 이전에 유닉스/리눅스에 빠져 있던 해커들이 아니었다.

이런 상황에서 Rails가 탄생했는데 Rails를 돌릴 마땅한 애플리케이션 서버가 없어서 mongrel 같은 서버를 루비 개발자들이 직접 만들었다. 그런데 자바 WAS들처럼 프로세스 관리 기능을 통째로 개발해서 탑재하기는 쉽지 않았고(물론 좋은 방법도 아니고) 아직 Rails가 충분히 안정화되지 않은 시기다보니 mongrel 프로세스가 죽는 일이 잦았다. 그러니 프로세스가 죽는지 모니터링하다가 죽으면 살려주자는 발상을 하게 되었고, 그 결과가 monit이다. monit이 Rails + mongrel 조합의 불안정성을 개선해주면서 인기를 끌게 된 것이다.

문제는 앞서서 본 것처럼 이런 목적에는 이미 init 시스템이 있었기 때문에 monit이 필요 없었다는 것이다. 명백한 ReinventTheWheel이다. 물론 바퀴를 더 좋게 개선하면 재발명할 수도 있다. 하지만 monit은 init보다 더 느리고, 더 리소스도 많이 먹었고, 더 불안정했다. running-processes에서는 다음과 같이 표현하고 있다.

“Wow. You reinvented init and cron, but managed to make them both less reliable and consume more CPU than I could’ve imagined.”

monit을 위한 변명

하지만 monit도 할 말이 있었을 것이다. 당시 upstart는 초기였고, systemd는 없었으며, init의 문제점은 오래 전부터 지적되어 왔었다. 게다가 init의 설정법은 루비 개발자들의 취향과 거리가 멀다. Managing Linux daemons with init scripts에서 보듯 /etc/init.d의 스크립트들은 별로 아름답지 않다. 이런 점들이 ReinventTheWheel을 좋아하는 루비 개발자들의 성향과 맞물렸을 것이다.

그리고 monit에는 init에서 소화하지 않는 기능이 하나 있었다. 프로세스가 죽었을 때 메일 등으로 알림을 보내주는 것이다(물론 이것도 불가능한 것은 아니었지만, 적어도 init의 기능은 아니었다). 이 두 가지가 그나마 monit을 위한 변명이 될 것이다.

유닉스의 철학

하지만, 이 변명으로는 충분하지 않다. 

 

 

Wiki at WikiNamu