Nginx 代理 websockets,连接未关闭

Nginx 代理 websockets,连接未关闭

我不知道问题出在哪里,但基本上我有一个 nginx 代理 websocket 连接到后端 ruby​​ 瘦服务器,该服务器为 Ruby on Rails 应用程序中的 websocket-rails 模块提供连接服务。除了很多套接字(可能全部)没有关闭之外,一切都运行良好,因此瘦服务器很快就会耗尽文件描述符。

我正在使用 nginx 1.4.2,这是我的配置:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}
server {
    listen       my.ip.num.ber:80;  
    server_name admin3.mydomain.com;
    root /home/apps/mydomain/current/public;
    try_files $uri/index.html $uri @admin3.mydomain.com;  
    access_log  /var/log/nginx/admin3.access.log  combined;
    error_log  /var/log/nginx/admin3.error.log error;
    location /websocket {  
        proxy_redirect off;
        proxy_pass http://localhost:3008;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        keepalive_timeout 90;
        proxy_connect_timeout 10;
        proxy_read_timeout 60;
        proxy_send_timeout 60;
    }
}

我正在使用 Thin 1.5.1,其配置如下:

port: 3008
user: ploy
group: ploy
pid: /home/apps/mydomain/shared/pids/thin.pid
timeout: 90
wait: 30
log: /home/apps/mydomain/shared/log/thin.log
max_conns: 1024
require: []
environment: production
max_persistent_conns: 512
servers: 1
threaded: false
#no-epoll: false
daemonize: true
chdir: /home/apps/mydomain/current
tag: admin3

每次只有几十个活动的 websocket 连接,从客户端浏览器或 websocket-rails 后端的角度来看,它们似乎可以正常建立和终止。但瘦服务器最终有 1025 个打开的文件描述符,其中大部分是套接字。

ls -l /proc/`ps aux | grep "thin server" | grep -v grep | head -n 1 | awk '{print $2}'`/fd

给出了这样的东西:

lrwx------. 1 root root 64 Aug 31 15:15 993 -> socket:[1319549665]
lrwx------. 1 root root 64 Aug 31 15:15 994 -> socket:[1319549762]
lrwx------. 1 root root 64 Aug 31 15:15 995 -> socket:[1319549850]
lrwx------. 1 root root 64 Aug 31 15:15 996 -> socket:[1319549974]
lrwx------. 1 root root 64 Aug 31 15:15 997 -> socket:[1319846052]
lrwx------. 1 root root 64 Aug 31 15:15 998 -> socket:[1319549998]
lrwx------. 1 root root 64 Aug 31 15:15 999 -> socket:[1319550000]

类似的事情似乎随后发生在 nginx 上:

ls -l /proc/`ps aux | grep "nginx: worker" | grep -v grep | head -n 1 | awk '{print $2}'`/fd

尽管套接字文件描述符的数量增长得比较慢,而且需要更长的时间才能达到 1025。事实上,我只见过一次。

所以,我有点不知所措,不知道问题出在我的 nginx 配置上,还是 Thin 上,或者是 websocket-rails 后端出了问题。我希望你们这些训练有素的人能看出一些明显的错误,即使你们不熟悉后端部分。

答案1

让我回答我自己的问题...错误的结果与上面列出的配置无关,这似乎仍然非常合理。

websocket-rails 模块的作者向我指出,对于 websocket 模块中触发的每个操作,我都会打开一个与 Redis 的新连接。显然,该连接没有正确关闭,导致打开的套接字无法关闭,并导致 Thin 陷入停顿。使用一次设置并重复使用的 Redis 连接改变了一切。

所以,这是一个相当模糊的情况,我甚至有点尴尬地将其呈现为服务器配置问题。

相关内容