nginx 1.7.9:反向代理 Web 套接字:服务停止/服务重启时挂起,永不退出

nginx 1.7.9:反向代理 Web 套接字:服务停止/服务重启时挂起,永不退出

我们使用 nginx 对一对 websocket 服务器进行负载平衡,但遇到了一个问题。

一旦它实际将流量连接到 Web 套接字服务器,它就不会正常退出或关闭。例如,service nginx stop、nginx -s quit 或 nginx -s reload 会导致一个或多个工作进程永远报告“工作进程正在关闭”。

流程如下:

  1. 使用下面的配置启动 nginx。
  2. 将流量传递到 nginx 端点(即使使用 Web 浏览器访问 443 端口并收到 404 错误也足够了)
  3. 使用服务控制或者发送退出命令
  4. nginx 现在已挂起。

我们在 centos v6 上运行 nginx

我们的编译选项和高级配置的详细信息:

    [root@nginx1 nginx]# nginx -V
    nginx version: nginx/1.7.9
    built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
    TLS SNI support enabled
    configure arguments: --user=nginx --group=nginx --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-http_gzip_static_module 
--with-http_ssl_module --add-module=/opt/nginx_upstream_check_module-master/

我们的配置如下。我们该如何解决这个问题?现在我们被迫强制关闭/重启 nginx 来更新配置。

worker_processes  2;

error_log  logs/error.log;

events {
    worker_connections  20000;
}

worker_rlimit_nofile    40000;

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    upstream websocketserver {
        server 192.168.2.16:3842 max_fails=1 fail_timeout=60s;
        server 192.168.2.19:3842 max_fails=1 fail_timeout=60s;
    }

    server {
        listen 192.168.2.28:80;

    location / {

        proxy_pass http://websocketserver;

        proxy_next_upstream    error timeout invalid_header http_500;
        proxy_connect_timeout  2;
        proxy_read_timeout      86400;

        # WebSocket support (nginx 1.4)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        }

        location / {
            deny all;
            return 404;
        }       

    }
}

答案1

可能netstat并且tcpdump对于调试以及lsof- 工作进程是否仍处于连接状态并交换数据?我注意到您的proxy_read_timeout时间是一天而不是默认的 60 秒,不知道这是否重要。这听起来像是一个 nginx 错误,并且可能这篇关于 ZLIB 压缩和 keepalive 的帖子与之相关:http://forum.nginx.org/read.php?2,170139,209671

答案2

我要做的是使用 附加到 nginx 进程strace,然后尝试关闭它并检查您的strace以查看它挂在哪个文件描述符上。使用此信息lsof来跟踪它正在等待哪个文件描述符并从那里开始。我猜可能是您的上游服务器之一导致了这种情况。

答案3

如果它是 websocket 服务器(如浏览器 websocket 协议),则需要向连接的浏览器发送 websocket 关闭并关闭套接字。192.168.2.*:3842 处的应用程序可以执行此操作。因此,您需要向该应用程序发送信号,告诉它向其连接的 websocket 发送关闭。

相关内容