On 16.09.2024 21:06, Konstantin Pavlov wrote:
>>>> а как Вам идея вместо двух unit-файлов nginx.service
>>>> и nginx-debug.service использовать только один unit-файл
>>>> nginx.service и использовать alternatives для переключения
>>>> бинарника /usr/sbin/nginx между release и debug версиями ?
>>>
>>> Мы поддерживаем несколько разных ОС в наших пакетах на nginx.org (и
>>> еще больше - для коммерческой версии), и не во всех них есть
>>> поддержка alternatives. По этой причине не хотелось бы это
>>> реализовывать для какой-то одной конкретной ОС если нельзя сделать
>>> везде одинаково.
>>
>> это можно сделать везде одинаково, на всех Linux/UNIX системах.
>>
>> если же переключение между release / debug версями происходит с помощью
>> двух отдельных сервисов nginx.service и nginx-debug.service, то в таком
>> случае переключение между ними происходит с потерей соединений клиентов
>
> Делать столько уникальной логики, опять же уходя от привычной многим и
> документированной системы alternatives, для очень редкой ситуации когда
> нужно запустить дебаг-версию?
Моя идея с симлинком /usr/sbin/nginx который указывает на release
или debug версию бинарника nginx - это плохая идея еще и потому,
что по стандарту FHS - "/usr should be shareable between various
FHS-compliant hosts and must not be written to. Any information
that is host-specific or varies with time is stored elsewhere".
alternatives использовать также нельзя, потому что
не во всех ОС есть поддержка alternatives и потому что
использование системы alternatives увеличивает хрупкость.
> Кажется, гораздо проще, если уж нельзя воспроизвести проблему на стенде,
> сделать временно:
>
> mv /usr/sbin/nginx /usr/sbin/nginx.bak
>
> mv /usr/sbin/nginx-debug /usr/sbin/nginx
>
> service nginx upgrade
>
А что делать в том случае, когда файловая система /usr смонтирована
в режиме read-only и не удается воспроизвести проблему на стенде?
Да и в том случае, когда файловая система /usr доступна на запись -
переименование исполняемых файлов - это неудобно как для самих
пользователей, так и для инженеров технической поддержки,
которые будут общаться с пользователями и помогать им.
Какое решение этой задачи будет более оптимальным?
service nginx upgrade
service nginx upgrade-to-debug
service nginx upgrade-to-release
Как технически это реализовать?
Upgrading Executable on the Fly
https://nginx.org/en/docs/control.html#upgrade
Когда старый master-процесс nginx делает этот шаг: "then starts
a new executable file that in turn starts new worker processes"
необходимо, он мог понимать, какой именно бинарник ему следует
запустить на выполнение - release или debug вариант бинарника.
Для этого - надо передать работающему master-процессу nginx
в процессе online upgrade дополнительно один бит информации.
когда передается 0 бит - тогда запускается /usr/sbin/nginx
когда передается 1 бит - тогда запускается /usr/sbin/nginx-debug
Каким образом это можно сделать? С помощью pid-файла.
В нормальном режиме работы pid-файл
имеет владельца root:root и права доступа 0644 (-rw-r--r--)
- в таком случае master-процесс nginx делает online upgrade
на обычную, release-версию бинарника /usr/sbin/nginx
Если же в момент получения master-процессом nginx сигнала USR2
на его pid-файл установлены права доступа 0664 (-rw-rw-r--)
- в таком случае master-процесс nginx делает online upgrade
на отладочную, debug-версию бинарника /usr/sbin/nginx-debug
В configure arguments при сборке задается
--sbin-path=/usr/sbin/nginx
было бы хорошо добавить еще один аргумент,
--sbin-debug-path=/usr/sbin/nginx-debug
по умолчанию, если явно не задано - добавляется
подстрока "-debug" к значению аргумента --sbin-path
в таком случае изменение логики работы nginx
будет минимальным в процессе online upgrade:
если pid-файл nginx имеет 1 бит в поле права на запись для группы,
тогда запустить бинарный файл, который задан в --sbin-debug-path
если 0 бит - запустить бинарный файл, который задан в --sbin-path
скрипт для выполнения команды service nginx upgrade-to-debug
файла /usr/libexec/initscripts/legacy-actions/nginx/upgrade-to-debug
===================================
#!/usr/bin/sh
#
# Legacy action script for "service nginx upgrade-to-debug"
pidfile=`/usr/bin/systemctl show -p PIDFile nginx.service | sed
's/^PIDFile=//' | tr ' ' '\n'`
chmod --quiet g+w ${pidfile}
exec service nginx upgrade
===================================
скрипт для выполнения команды service nginx upgrade-to-release
файла /usr/libexec/initscripts/legacy-actions/nginx/upgrade-to-release
===================================
#!/usr/bin/sh
#
# Legacy action script for "service nginx upgrade-to-release"
pidfile=`/usr/bin/systemctl show -p PIDFile nginx.service | sed
's/^PIDFile=//' | tr ' ' '\n'`
chmod --quiet g-w ${pidfile}
exec service nginx upgrade
===================================
существующий скрипт для выполнения команды service nginx upgrade
файл /usr/libexec/initscripts/legacy-actions/nginx/upgrade
- остается без изменений.
и тогда - в любой момент времени можно будет сделать
on the fly переключение между release и debug версиями
nginx без потери клиентских соединений, всего одной командой.
причем, этот метод будет работать на любой версии Linux
и тогда можно будет обойтись всего одним unit-файлом nginx.service
и можно будет полностью отказаться от unit-файла nginx-debug.service
такой вариант решения будет иметь максимальную надежность,
потому что не будут использоваться симлинки и alternatives
будет требовать минимальное количество изменений в коде nginx
и при этом - будет максимально удобным для пользователей nginx,
потому что позволит переключаться между release и debug версями
nginx без потери соединений выполнив всего лишь одну команду.
--
Best regards,
Gena
_______________________________________________
nginx-ru mailing list
nginx-ru@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-ru