Skip to content

Использование runit вместо Init и вывод логов в файл

04/04/2011

Я достаточно долгое время использовал связку Init+Monit для запуска скриптов node, но со временем стал натыкаться на минусы такой связки. Одна из самых серьёзных проблем — отсутствие возможности вывести лог в разные файлы в ранних версиях start-stop-daemon. Версия, поставляемая с Debian Lenny не поддерживает такой функционал, а сборка новой версии тянет за собой уйму непонятного барахла. В итоге, попробовав разные варианты, я остановился на runit как замене Init-скриптам.

Установка и настройка

Для большинства систем runit ставится из стандартного менеджера пакетов (apt-get install runit для Debian). Если в Вашем менеджере нужного пакета нет, можно скачать исходники для сборки с официальной страницы.

Каждому сервису в runit соответствует директория в /etc/sv. В этой директории создаём файл запуска run:

mkdir /etc/sv/testservice
vim /etc/sv/testservice/run

В файле run пишем строку для запуска нашего скрипта, с перенаправлениями ввода-вывода, без демонизации (&), но с exec:

exec node /etc/mysite/server.js 1>>/var/log/mysite/output 2>>/var/log/mysite/error

Ставим этому файлу разрешение на выполнение:

chmod +x run

Теперь чтобы запустить сервис надо передать runit команду и имя директории внутри /etc/sv:

sv start testservice

Чтобы остановить сервис, вторым параметром передаётся stop, чтобы перезапустить — restart.

Чтобы проверить runit я использовал немного модифицированный «Hello World» с официального сайта:

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
  console.log('Log message #' + i);
  console.error('Err message #' + i);
  i++;
}).listen(8124, "192.168.175.128");
console.log('Server running at http://127.0.0.1:8124/')

console.log выводит строку в стандартный поток вывода (stdout), console.error выводит строку в stderr. Строки, переданные в console.log будут выводиться в /var/log/mysite/output, то что передано в console.error будет записано в /var/log/mysite/error.

(Кстати, если сделаете то же самое и увидите что с каждым обновлением в лог попадают сразу две строки с последовательными номерами, не спешите искать баг в коде. Скорее всего Ваш браузер запрашивает вместе со страницей файл favicon.ico для сайта.)

Чтобы прикрутить runit к monit’у, можно создать симлинк в директории /etc/init.d/ на /usr/bin/sv. При таком вызове runit будет запускать/останавливать сервис, соответствующий имени симлинка:

ln -s /usr/bin/sv /etc/init.d/testservice

Теперь при вызове /etc/init.d/testservice start Ваш скрипт будет запущен. Так проще будет перейти с Init на runit если Вы всё таки задумаете это сделать🙂

Ссылки по теме

8 комментариев
  1. hostmaster permalink

    раз уж используется супервайзер runit то стоит всё делать в этой идеологии.

    === BEGIN /etc/sv/testservice/run ===
    #!/bin/sh
    NODE_USER=nobody
    exec 2>&1
    exec chpst -u$NODE_USER node /etc/mysite/server.js
    === END ===
    я бы еще добавил softlimit но это по вкусу

    логирование тоже через runit сервис
    === BEGIN /etc/sv/testservice/log/run ===
    #!/bin/sh
    exec chpst -ulog svlogd -tt ./main
    === END ===

    • Здорово, надо будет поглубже покопать. С chpst я не работал пока, хотя знаю что он есть в наборе (не было надобности ограничивать процесс).

      • hostmaster permalink

        я бы еще добавил немного bash magic, чтобы использовать один run для разных сайтов с разными конфигом

        • У меня есть немного bash magic для генерации конфигов/скриптов запуска (подстановка версии ноды, порта и т.п.), но об этом пока не писал. У меня просто обычно один сайт на сервере.

  2. ai.bread permalink

    А чем этот вариант отличается например от forever? Как раз подошел в разработке к этапу, когда все должно запускаться по-человечески и пытаюсь найти оптимальный вариант

    • Forever я честно говоря пока не пробовал (думаю потом опишу и его тоже). Судя по всему это замена для всей связки Runit + Monit: управляет перенаправлением ввода-вывода, предоставляет способ запускать и перезапускать процесс, поднимает его в случае необходимости.

  3. ai.bread permalink

    Будем ждать описания! А пока сам потихоньку попробую все по полочкам для себя разложить ))

  4. Андрей permalink

    По моему вы заблуждаетесь. И ему до того же Runit далеко. Кстати Runit же прекрасно следит за живучестью сервиса и поднимает его если тот упал и Monit ему не нужен (ну разве только для того, чтобы поднять Runit в случае падения).

    К тому же Runit уже заматерелый продукт и шансов получить неприятную багу с ним меньше.

    P.S. Аналог Runit это http://supervisord.org. Он написан на python и по виду (конфиги и удобство) выглядит приятней Runit. К тому же можно управлять сервисами через xml-rpc. А еще есть дополнение для него, которое позволяет следить за разными параметрами и в случае чего перезапускает сервис. Скажем можно отслеживать утечки памяти.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: