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