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