我有一个 tomcat 实例处理请求,并且我有 nginx 作为该 tomcat 实例的反向代理。
当我更新 Java 应用程序时,大约需要 10 秒。但这 10 秒内网站瘫痪,nginx 返回 HTTP 503 页面。
我希望 nginx 能做到:暂停所有传入连接,直到后端启动。然后开始为它们提供服务。最好进行一些智能检查,例如“/”返回 HTTP 200。在我看来,用户最好等待 10 秒,而不是看到 HTTP 503 页面。
我不想为此使用集群。我使用应用内缓存,而且我的 Web 应用程序负载远非高。集群会带来很多问题,我不想花时间解决这些问题。
我使用以下指令连接到 tomcat:
proxy_pass http://127.0.0.1:8080;
答案1
如果您使用 fastcgi 与应用程序通信,则将fastcgi_read_timeout
、fastcgi_connect_timeout
和设置fastcgi_send_timeout
为所需的值,以便 nginx 可以接受“保留”客户端并等待应用程序响应。(即 60 秒)
浏览器将保持空白,直到应用程序响应,最多等待 60 秒才会抛出 503(服务不可用)或 504(网关超时),但应用程序上的套接字/端口必须在高负载下进行监听,否则 nginx 可能会从后端收到“连接被拒绝”并向客户端抛出 503。如果您的应用程序崩溃并移除套接字或关闭监听端口,我不能 100% 确定这些调整是否会对您有所帮助,但最好对其进行配置。
如果您通过代理与应用程序对话,则正确变量的名称是proxy_read_timeout
、proxy_connect_timeout
和proxy_send_timeout
。
也许您只需要read
和connect
。
答案2
最好的方法取决于 tomcat 传递的内容的性质。
如果 tomcat 生成的内容无法在 nginx 端缓存,请增加
proxy_connect_timeout
和proxy_read_timeout
到10s
并使用上下文重新加载,而不是重新启动 tomcat(reloadable=true
在上下文文件中设置或使用 JMX/Tomcat 管理器调用来强制 web 应用程序重新加载例如http://[hostname]:[port]/manager/reload?path=[/path/to/your/webapp]
)。如果 tomcat 生成的内容可以在 nginx 端缓存,那么您可以采用前面的步骤,但将超时设置为一些合理的值。然后将更多内容放入您的配置中:使用
proxy_cache_use_stale
和proxy_cache_lock
一起proxy_cache_lock_timeout
为您的访问者提供过时的页面,同时您允许一次一个请求尝试更新缓存,避免应用程序重新部署时响应时间更长。
您也可以寻找第三方模块上游检查模块(或者使用叉子引擎实现这个天生地) 实现更智能的健康检查。
如果你负担得起,你也可以使用 nginx 的商业版本nginx 加它原生实现了这个功能(并且允许更智能的 http 检查条件),health_check
和match
指令。