我有一个nodejs应用程序永远在nginx后面运行。 当我部署新的代码,我只是forever restart但我不能在这么短的时间内获得502。
如何configurationnginx在502的情况下在这个上游服务器上继续重试? 我试着设置proxy_connect_timeout , proxy_read_timeout和proxy_send_timeout为例如30s但我立即得到502无论如何:(
我的网站conf是:
upstream my_server { server 127.0.0.1:3000 fail_timeout=0; keepalive 1024; } server { listen 3333; server_name myservername.com; access_log /var/log/nginx/my_server.log; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; # retry upstream on 502 error proxy_connect_timeout 30s; proxy_send_timeout 30s; proxy_read_timeout 30s; proxy_pass http://my_server; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_redirect off; } }
如果上游不可用,是否可以在短时间内缓冲请求?
这最终听起来像是后端的一个问题:nginx向你的后端发出一个请求,连接被立即拒绝,所以,nginx没有其他的select把错误传递给用户,因为没有指定其他的上游,而你指定的timeout值在这里没有效果,因为nginx根本不需要等待任何东西。
我现在不是forever是什么,或者它是如何工作的,但是有一些可能的解决scheme想到了。
上游发生的事情有两种可能性:
“永远”可能会接受连接,并立即返回错误。 在这种情况下,听起来像你真正应该问的是如何使它不会错误地处理连接,而是等到你的应用程序完成部署,然后处理请求。 tomcat服务器上的opengrok应用程序有这个问题。
没有人正在监听应用程序应该运行的端口,因此,内核立即丢弃数据包,并立即返回TCP RST数据包。
如果TCP RST是原因,那么可以通过forever保持侦听套接字来解决这个问题,或者通过configuration内核将input数据包排队一段时间,以便稍后有人select它们,以便当forever启动时它将有一个完整的队列准备服务。
configuration内核不会在没有人监听的时候发出TCP RST ,那么你在nginx中的timeout会有效果。 随后,configurationnginx向另一个上游发出第二个请求。
如果你解决上述任何一种情况,你就完成了。
否则,你必须尝试configurationnginx来解决这个问题:
你可以用proxy_cache_use_stale尝试proxy_cache_use_stale 。
您可以尝试使用error handling程序:请参阅proxy_intercept_errors (可能只适用于您获得的503从后端传递)和error_page 。 你会想浪费时间在error handling程序中,直到你的应用程序恢复,然后向你的应用程序发出请求。
sleep() 。 嘿,你可以简单地实现这一点,试图代理到一个TCP端口,你block drop放在防火墙,这将激活你的nginx超时。 随后,configurationnginx发出第二个请求。 如果你实现了一个涉及timeout激活的上述方法,那么随后需要对后端进行额外的请求。 你可以使用upstream指令来指定同一个服务器多次,或者如果不被接受,可以通过防火墙镜像一个端口,或者更好的是,你可以在第一个服务器上运行多个独立的应用服务器地点。
这将我们带回到您的应用程序服务器:如果它不能处理干净的重新部署的问题,那么也许你应该运行两个这样的应用程序服务器,并使用nginx在它们之间进行负载平衡。 或者重新部署它们,然后在实际准备好之后将nginx切换到新的副本。 否则,你怎么可能确定你的客户会愿意等30秒让API响应呢?