Правильный способ использования reuseport в виртуальном хосте nginx

Правильный способ использования reuseport в виртуальном хосте nginx

Я использую 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вы это сделаете, зависит от ваших предпочтений. Но как правило и для ясности я предлагаю обозначить один из servers 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
}

Связанный контент