/usr/sbin/nginx alternatives

Hennadii Makhomed gmm на csdoc.com
Вт Сен 17 08:10:25 UTC 2024


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