Я не понимаю, где находится проблема, но в основном у меня есть nginx, проксирующий соединения websocket с внутренним тонким сервером ruby, который обслуживает соединения с модулем websocket-rails в приложении Ruby on 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;
}
}
Я использую тонкий 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-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, или с тонким, или это что-то в бэкэнде websocket-rails. Я надеюсь, что некоторые из ваших натренированных глаз могут увидеть что-то явно неправильное, даже если вы не знакомы с внутренними частями.
Позвольте мне ответить на свой вопрос ... То, что было не так, оказалось ничем с конфигурацией, изложенной выше, которая все еще кажется вполне разумной.
Автор модуля websocket-rails указал мне, что я открываю новое соединение с Redis для каждого действия, запускаемого в модуле websocket. По-видимому, это соединение не было закрыто должным образом, из-за чего открытые сокеты не закрывались, а тонкое соединение останавливалось. Использование соединения Redis, установленного один раз и повторно использованного, изменило все.
Итак, довольно непонятная ситуация, и мне немного неловко даже представить ее как проблему конфигурации сервера.