Итак, у меня есть сервер nginx, работающий по https с Sinatra. Когда я пытаюсь загрузить файл jnlp в конфигурации, которая отлично работает по Mongrel и http (без s), сервер nginx не может обслужить файл с ошибкой 504. Последующая проверка журналов показывает, что эта ошибка вызвана переполнением доступного числа дескрипторов файлов, т. е. "24: слишком много открытых файлов". Запуск
sudo lsof -p <nginx worker pid>
выдает мне огромный список файлов, все они выглядят примерно так:
nginx 1771 nobody 11u IPv4 10867997 0t0 TCP localhost:44704->localhost:https (ESTABLISHED)
nginx 1771 nobody 12u IPv4 10868113 0t0 TCP localhost:https->localhost:44704 (ESTABLISHED)
nginx 1771 nobody 13u IPv4 10868114 0t0 TCP localhost:44705->localhost:https (ESTABLISHED)
nginx 1771 nobody 14u IPv4 10868191 0t0 TCP localhost:https->localhost:44705 (ESTABLISHED)
nginx 1771 nobody 15u IPv4 10868192 0t0 TCP localhost:44706->localhost:https (ESTABLISHED)
nginx 1771 nobody 16u IPv4 10868255 0t0 TCP localhost:https->localhost:44706 (ESTABLISHED)
nginx 1771 nobody 17u IPv4 10868256 0t0 TCP localhost:44707->localhost:https (ESTABLISHED)
nginx 1771 nobody 18u IPv4 10868330 0t0 TCP localhost:https->localhost:44707 (ESTABLISHED)
nginx 1771 nobody 19u IPv4 10868331 0t0 TCP localhost:44708->localhost:https (ESTABLISHED)
nginx 1771 nobody 20u IPv4 10868434 0t0 TCP localhost:https->localhost:44708 (ESTABLISHED)
Увеличение количества файлов, которые можно открыть, не поможет, потому что тогда nginx просто превысит этот лимит. И неудивительно, похоже, что он находится в каком-то цикле, чтобы вытащить все доступные файлы.
Есть идеи, что происходит и как это исправить?
РЕДАКТИРОВАТЬ:nginx 0.7.63, ubuntu linux, sinatra 1.0
ПРАВКА 2:Вот код, вызывающий проблемы. Это sinatra, обслуживающий jnlp, в чем я наконец разобрался:
get '/uploader' do
#read in the launch.jnlp file
theJNLP = ""
File.open("/launch.jnlp", "r+") do |file|
while theTemp = file.gets
theJNLP = theJNLP + theTemp
end
end
content_type :jnlp
theJNLP
end
Если я обслуживаю это с помощью Sinatra через Mongrel и http, все работает нормально. Если я обслуживаю это с помощью Sinatra и nginx через https, я получаю указанную выше ошибку. Все остальные части веб-сайта кажутся эквивалентными.
РЕДАКТИРОВАТЬ:С тех пор я обновился до Passenger 2.2.14, Ruby 1.9.1, Nginx 0.8.40, OpenSSL 1.0.0a, но никаких изменений.
РЕДАКТИРОВАТЬ:Виновником, похоже, являются бесконечные перенаправления из-за использования SSL. Я не знаю, как это исправить, кроме как разместить файл jnlp в корневом каталоге сервера (чего я бы предпочел не делать, поскольку это ограничивает меня одним приложением на основе jnlp за раз).
Соответствующие строки из nginx.conf:
# HTTPS server
#
server {
listen 443;
server_name MyServer.org
root /My/Root/Dir;
passenger_enabled on;
expires 1d;
proxy_set_header X-FORWARDED_PROTO https;
proxy_set_header X_FORWARDED_PROTO https;#the almighty google is not clear on which to use
location /upload {
proxy_pass https://127.0.0.1:443;
}
}
Самое забавное, что, во-первых, я помещал jnlp в каталог с названием 'uploader', а не 'upload', но это все равно, похоже, вызывало проблему, поскольку директива proxy_pass появилась в журналах. Во-вторых, снова, перемещение jnlp в root позволило избежать проблемы, поскольку не было никакого проксирования из-за ssl.
Итак, как избежать бесконечного цикла proxy_pass в nginx?
решение1
nginx прослушивает порт 443. Когда вы получаете запрос на /uploader
, вы проксируете на ... порт 443. Это nginx. Похоже, вы должны проксировать на свое приложение sinatra, которое прослушивает какой-то другой порт? Я не очень хорошо знаю nginx, но это выглядит неправильно.