Я использую nginx в качестве обратного прокси-сервера с сервером приложений gunicorn (приложение Django).
В моем файле виртуального хоста nginx есть два server
блока. Первый перенаправляет www
трафик во второй (который обрабатывает non-www
, https
трафик).
В частности, бывший блок местоположения:
server {
server_name www.example.com;
listen 443 ssl http2;
listen [::]:443 ssl http2;
return 301 https://example.com$request_uri;
}
Последний блок локации:
server {
server_name example.com;
listen 443 ssl http2 reuseport;
listen [::]:443 ssl http2 reuseport;
# other directives here
}
Обратите внимание на использование reuseport
в последнем блоке.
Если я вставлю reuseport
оба блока, то получу ошибку: nginx: [emerg] duplicate listen options for 0.0.0.0:443 in /etc/nginx/sites-enabled/vhost:62
.
Если я вставляю его только в первый блок, он работает. Я не знаю, где его правильно разместить, в первом блоке или во втором. Может кто-нибудь прояснить?
Я понимаю, что этот reuseport
параметр предписывает nginx создать отдельный прослушивающий сокет для каждого рабочего процесса, позволяя ядру распределять входящие соединения между рабочими процессами (для обработки нескольких пакетов, отправляемых между клиентом и сервером).
Но это не помогает мне понять, почему я не могу использовать его reuseport
в обоих вышеупомянутых блоках или в каком из них мне следует его использовать (учитывая, что я могу использовать его только в одном).
решение1
В NGINX вы указываете параметры прослушивания сетевого сокета только один раз в конфигурации, и они «применяются» ко всем другим настроенным server
сокетам, которые прослушивают тот же сокет (порт). Цитатадокументы:
Директива listen может иметь несколько дополнительных параметров, специфичных для системных вызовов, связанных с сокетами. Эти параметры могут быть указаны в любой директиве listen, но только один раз для заданной пары адрес:порт.
Итак, из сообщения об ошибке следует, что reuseport
для каждого уникального listen
адреса+порта следует указывать только один раз.
В каком месте server
вы это сделаете, зависит от ваших предпочтений. Но как правило и для ясности я предлагаю обозначить один из server
s default_server
директивой, которая:
если присутствует, то сервер станет сервером по умолчанию для указанной пары адрес:порт. Если ни одна из директив не имеет параметра default_server, то первый сервер с парой адрес:порт будет сервером по умолчанию для этой пары.
Затем поместите параметры прослушивания в этот блок сервера (где вы указали default_server
).
Например
server {
server_name www.example.com;
listen 443 ssl http2;
listen [::]:443 ssl http2;
return 301 https://example.com$request_uri;
}
server {
server_name example.com;
listen 443 ssl http2 default_server reuseport;
listen [::]:443 ssl http2 default_server reuseport;
# other directives here
}