nginx虚拟主机中使用reuseport的正确方法

Has*_*aig 5 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;
}
Run Code Online (Sandbox Code Playgroud)

后一个位置块是:

server {

    server_name example.com;
    listen 443 ssl http2 reuseport;
    listen [::]:443 ssl http2 reuseport;

    # other directives here
}
Run Code Online (Sandbox Code Playgroud)

reuseport请注意后一个块中的使用。

如果我放入reuseport两个块,则会收到错误:nginx: [emerg] duplicate listen options for 0.0.0.0:443 in /etc/nginx/sites-enabled/vhost:62

如果我将它单独插入前一个块中,它就可以工作。我对正确放置它的位置感到困惑,前一个块还是后一个块。有人可以澄清一下吗?


据我了解,该reuseport参数指示 nginx 为每个工作进程创建一个单独的侦听套接字,允许内核在工作进程之间分配传入连接(以处理客户端和服务器之间发送的多个数据包)。

但这并不能帮助我理解为什么我不能reuseport在上述两个块中使用它,或者我应该在哪一个块中使用它(假设我只能在一个块中使用它)。

Dan*_*nin 4

在 NGINX 中,您只需在配置中指定一次网络套接字的侦听选项,并且它们“应用”到server侦听同一套接字(端口)的所有其他配置。引用文档

Listen 指令可以有几个特定于套接字相关系统调用的附加参数。这些参数可以在任何监听指令中指定,但对于给定的地址:端口对只能指定一次。

因此,您必须从错误消息中解读出,您应该只reuseport为每个唯一的listen地址+端口指定一次。

您执行此操作的方式server取决于您的偏好。但作为一项规则,为了清楚起见,我建议指定其中一个serverwithdefault_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
}

Run Code Online (Sandbox Code Playgroud)