nginx 服务器通过 https 使用所有可用的文件句柄(upd:无限循环?)

nginx 服务器通过 https 使用所有可用的文件句柄(upd:无限循环?)

因此,我有一个使用 Sinatra 通过 https 工作的 nginx 服务器。当我尝试下载 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

如果我通过 Mongrel 和 http 使用 Sinatra 来提供此服务,则一切正常。如果我通过 https 使用 Sinatra 和 nginx 来提供此服务,则会出现上述错误。网站的所有其他部分似乎都相同。

编辑:此后,我已升级到 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 移到根目录中可以避免此问题,因为由于 ssl 而不存在任何此类代理。

那么,如何避免 nginx 中的无限 proxy_pass 循环?

答案1

nginx 正在监听端口 443。当您收到请求时/uploader,您会代理到...端口 443。这就是 nginx。似乎您应该代理到您的 sinatra 应用程序,而该应用程序正在监听其他端口?我不太了解 nginx,但看起来不对劲。

相关内容