我们使用 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;
}
}
}
可能
netstat
并且tcpdump
对调试很有用lsof
- 工作进程是否仍然连接并交换数据?我注意到你proxy_read_timeout
是一天而不是默认的 60 年代,我想知道这是否重要。这听起来像一个 nginx 错误,可能有关 ZLIB 压缩和 keepalive 的这篇文章是相关的:http: //forum.nginx.org/read.php?2,170139,209671我要做的是使用 附加到 nginx 进程
strace
,然后尝试将其关闭并检查它strace
以查看它挂起的文件描述符。使用此信息lsof
来跟踪它正在等待的文件描述符并从那里开始。我的猜测是它可能是您的上游服务器之一导致了这种情况。如果它是像浏览器 websocket 协议这样的 websocket 服务器,它需要将 websocket 关闭发送到连接的浏览器并关闭套接字。位于 192.168.2.*:3842 的应用程序将能够这样做。因此,您需要向该应用程序发送一个信号,告诉它向其连接的 websocket 发送关闭。