location

Maxim Dounin mdounin на mdounin.ru
Вт Июл 9 08:51:19 UTC 2019


Hello!

On Mon, Jul 08, 2019 at 07:24:33PM +0300, Slawa Olhovchenkov wrote:

> On Mon, Jul 08, 2019 at 07:11:59PM +0300, Maxim Dounin wrote:
> 
> > > > > action тут разный. я на этом внимание не заострил, думал и так понятно
> > > > 
> > > > Понятно.  И также понятно, что даже при одном и том же action - 
> > > > приведённые команды делают разное, и результаты могут кардинально 
> > > > отличаться в том числе из-за этого.  Именно поэтому я и указал на 
> > > > эту проблему как на одну из возможных причин наблюдаемого 
> > > > поведения.  Дабы подобную проблему гарантированно исключить - 
> > > > лучше всего использовать одну и ту же форму команды.
> > > 
> > > так не бывает же `nginx -s restart`, т.е. `nginx stop && nginx start`
> > 
> > Зато бывает "service nginx reload" и "service nginx restart".
> > 
> > (Ну и вообще, использовать "nginx -s ..." на юникс-системах - 
> > странно.  Как минимум попадаем на двойной парсинг конфигурации, 
> > как максимум - на невозможность использовать эти команды, если 
> > PID-файл надо переложить в другое место.)
> 
> набирать короче, давно заучил, а эти service вечно меняются...

Форма "service <name> <action>" работает начиная с FreeBSD 7.3, и 
с момента появления не менялась.

> > > > - После чего был сделан reload - и привёл к той же ошибке "module 
> > > >   ... is already loaded", что было проигнорировано.  Так
> > > 
> > > нет, он не нашел ndk_* символов.
> > > после чего я добавил строку с загрузко ndk_http.
> > 
> > Не нашёл символов - в процессе тестирования конфигурации с помощью 
> > "nginx -t" и/или при парсинге конфигурации в процессе запуска 
> > "nginx -s"?
> 
> вот тут не помню.
> 
> > Ожидаемо, так как у свежезапущенных экземпляров nginx'а нет 
> > загруженных модулей, и они получают то, что было на диске.  И это 
> > одна из причин, почему reload не стоит предварять запуском "nginx -t", 
> > и не стоит использовать "nginx -s".
> 
> ничего не понял.

В рассматриваемом случае содержимое бинарных файлов на диске 
(nginx + модули) - поменялось.  Более того, поменялось - 
несовместимо, для работы старых бинарных файлов требовалась одна 
конфигурация, для работы новых - другая.

Когда такое происходит, использование "nginx -t" и "nginx -s 
<action>" совместно с перезагрузкой конфигурации на лету - 
невозможно.  Проблема в том, что эти команды требуют конфигурацию, 
совместимую с новыми бинарными файлами, тогда как для перезагрузки 
конфигурации работающего nginx'а - нужна конфигурация, совместимая 
со старыми бинарными файлами.

Проще всего - в такую ситуацию не попадать, и после обновления 
бинарных файлов (что самого nginx'а, что модулей) - сразу делать 
upgrade, синхронизируя бинарники на дисках, и в памяти.  Но вообще 
говоря работа в несинхронизированном состоянии тоже возможна - 
просто надо пользоваться сигналами, а не пытаться использовать 
nginx с диска (который не совпадает с тем, что в памяти).

> > > >   происходит, потому что с помощью reload'а нельзя изменить ранее 
> > > >   загруженный модуль - so-шка уже в памяти, и при попытке её снова 
> > > >   открыть - откроется старая so-шка.  Чтобы загрузить новые модули 
> > > >   после изменения их so-файлов на диске - нужно делать upgrade.
> > > 
> > > а чего он их тогда полез открывать-то?
> > > меня устроили бы старые модули.
> > 
> > В новой конфигурации - новый список модулей, они открываются / 
> > загружаются в соответствии с тем, что задано в директивах 
> > load_module в конфиге.  Поскольку в список добавился ndk - nginx 
> > его попытался загрузить, поскольку в результате оказалось 
> > загружено два одинаковых модуля - выдал ошибку и откатился на 
> > предыдущую конфигурацию.
> 
> погоди. изначально список модулей не менялся, но конфигурация не
> применилась потому что при открытии модуля выяснилось что его разбили
> на два и теперь у него символы не находятся.

Нет.  Если бы конфигурацию, не меняя, перегрузили в работающем 
nginx'е с помощью сигналов - она бы прекрасно применилась.  
Проблема именно в том, что конфигурацию - изменили на такую, 
которая не совместима с работающим nginx'ом.

> но как сказанно выше -- изменять загруженные модули нельзя, т.е. его и
> не надо было открывать и тогда этой ошибки и не было бы. так?

Когда дело дошло до загрузки конфигурации в работающем nginx'е - в 
этой самой конфигурации присутствовал как ранее загруженный 
модуль, так и дополнительный модуль, дублирующий часть ранее 
загруженного.  Ранее загруженный модуль - фактически, просто 
перенесли как есть в новую конфигурацию в памяти.  А при попытке 
загрузить дополнительный модуль (загружать новые модули - можно, в 
общем случае никаких проблем с этим нет) - произошла ошибка, из-за 
этого конфигурация не применилась.

Единственное действие, которое могло бы предотвратить проблему - 
это не загружать _новый_ модуль.  Но догадаться, что явно 
добавленный в конфигурацию модуль на самом деле загружать не надо - 
nginx не может.

-- 
Maxim Dounin
http://mdounin.ru/


Подробная информация о списке рассылки nginx-ru