我们使用 nginx 对一对 websocket 服务器进行负载平衡,但遇到了一个问题。
一旦它实际将流量连接到 Web 套接字服务器,它就不会正常退出或关闭。例如,service nginx stop、nginx -s quit 或 nginx -s reload 会导致一个或多个工作进程永远报告“工作进程正在关闭”。
流程如下:
- 使用下面的配置启动 nginx。
- 将流量传递到 nginx 端点(即使使用 Web 浏览器访问 443 端口并收到 404 错误也足够了)
- 使用服务控制或者发送退出命令
- 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 发送关闭。