systemd: PID file /var/run/nginx.pid not readable (yet?) after start.
Konstantin Tokarev
annulen на yandex.ru
Пт Ноя 24 11:43:29 UTC 2017
24.11.2017, 14:30, "Gena Makhomed" <gmm на csdoc.com>:
> On 24.11.2017 6:12, Maxim Dounin wrote:
>
>>>> Но сама идея, что все должны сесть и заняться выпиливанием
>>>> стандартного паттерна, который работал десятки лет, и делать
>>>> вместо это что-то своё с синхронизацией - не взлетит.
>
>>> Эта идея уже взлетела. Если демон состоит из одного процесса
>>> - systemd может однозначно узнать его pid, проблемы могут возникать
>>> только с теми демонами, которые состоят из нескольких процессов.
>>> Из известных мне сервисов состоящих из более чем одного процесса:
>
>>> * postfix - сделали синхронизацию и проблем с systemd больше нет.
>>> * httpd - перевели на Type=notify и проблем с systemd больше нет.
>>> * php-fpm - перевели на Type=notify и проблем с systemd больше нет.
>>> * nginx - только с этим сервисом наблюдаются проблемы под systemd.
>
>> Давайте, всё-таки, опеределимся: мы за всё хорошее против всего
>> плохого (== чтобы демоны писали pid-файлы до выхода запущенного
>> процесса, потому что по другому - плохо), или вопрос исключительно
>> в том, чтобы systemd не ругался в логи?
>
> Так ведь systemd и ругается в логи потому что по другому - плохо.
> Например, команда "/etc/init.d/nginx start ; /etc/init.d/nginx stop"
> будет глючить на системах, где nginx запускается в виде SysV сервиса.
>
>> Если за всё хорошее - то проблема, очевидно, не ограничевается
>> сервисами из более чем одного процесса, и не решается переводом на
>> Type=notify. Она вообще ортогональна существованию systemd. И
>> идея её решения, очевидно, не взлетела, и уже наверное не взлетит.
>
> В MacOS X есть launchd - там сервисам вообще запрещено делать fork()
> и вызывать функцию daemon() - и ничего, никто еще умер, все работает.
> https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
В daemontools, runit и т.п., которые появились еще раньше, fork тоже не поощряется
>
> systemd - это такой же launchd, но для системы Linux. Только для своих
> конфигурационных файлов он использует ini синтаксис вместо формата xml
> и небезуспешно пытается быть обратно совместимым со старыми SysV Daemons
>
> Но свои специфичные требования к сервисам есть и у systemd:
> https://www.freedesktop.org/software/systemd/man/daemon.html
>
> 15. Call exit() in the original process. The process that invoked
> the daemon must be able to rely on that this exit() happens
> after initialization is complete and all external communication
> channels are established and accessible.
>
> Одним из таких communication channels как раз и является pid-файл.
>
>> Если чтобы systemd не ругался - то проблема, очевидно, не в том,
>> чтобы сделать хорошо, а в том, убрать конкретную ругань (которая
>> не несёт практического смысла, см. ниже). И предолженный ранее
>> workaround про sleep 0.1 - вполне себе в этом ключе же решение?
>
> sleep 0.1 - это race condition на ровном месте, плохой workaround.
> Лучше будет если такого workaround`а в unit-файлах nginx не делать.
>
> Когда команда "/etc/init.d/nginx start ; /etc/init.d/nginx stop"
> глючит - это ведь отрицательно сказывается на репутации nginx.
> И эта проблема вообще ортогональна существованию systemd.
>
>>> systemd однозначно определяет pid демонов состоящих из одного процесса
>>> и поэтому для них в юнит-файле можно вообще не указывать опцию PIDFile=
>>> - все будет работать как надо даже если они стартуют без синхронизации.
>>>
>>> Вот что говорит Lennart Poettering из Red Hat:
>>>
>>> If you use Type=forking, then you'll get away with not specifiying a
>>> PID file in most cases, but it's racy as soon as you have more than
>>> one daemon process, and nginx appears to be one of this kind, hence
>>> please specify PIDFile=.
>>>
>>> https://lists.freedesktop.org/archives/systemd-devel/2017-November/039833.html
>>
>> Ну вот я посмотрел на это место чуть подробнее, и имею сказать,
>> что это не совсем соответствует действительности. Единственное,
>> для чего нужен PIDFile в случае nginx'а - это чтобы systemd
>> нормально реагировал на binary upgrade.
>>
>> Для правильного детектирования основного процесса при запуске
>> PIDFile не нужен, так как master-процесс - единственный, у кого
>> parent'ом systemd, у остальных процессов parent'ом будет master.
>> И соответственно все остальные процессы успешно отфильтрует вот
>> этот код,
>> https://github.com/systemd/systemd/blob/master/src/core/cgroup.c#L1727:
>>
>> /* Ignore processes that aren't our kids */
>> if (get_process_ppid(npid, &ppid) >= 0 && ppid != mypid)
>> continue;
>>
>> Однако если PIDFile не указывать, то "service nginx upgrade"
>> приведёт к тому, что после выхода старого мастера systemd будет
>> считать, что nginx умер, и убьёт все новые процессы. Поэтому
>> PIDFile указывать таки надо.
>>
>> Соответственно имеем то что имеем: PIDFile указывать надо, от
>> этого на старте могут появляться сообщения про "PID file not ... yet?".
>> Сообщения эти безвредные, и ни на что не влияют, кроме собственно
>> появления самих сообщений.
>>
>> Если идти по пути синхронизации через pipe, то патч получается
>> как-то такой. Не могу сказать, что он мне нравится, особенно в
>> контексте решения задачи "чтобы у systemd в логе стало на одну
>> строчку меньше".
>
> Есть проблема "/etc/init.d/nginx start ; /etc/init.d/nginx stop"
> на старых системах, использующих SysV систему инициализации.
>
> И есть еще проблема не полной совместимости nginx с требованиями,
> которые systemd предъявляет к SysV Daemons - это имиджевая проблема.
>
> Сообщение "PID file not ... yet?" - это только следствие этих проблем.
>
> --
> Best regards,
> Gena
>
> _______________________________________________
> nginx-ru mailing list
> nginx-ru на nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-ru
--
Regards,
Konstantin
Подробная информация о списке рассылки nginx-ru