如何让Nginx反向代理等到上游上线



我有一个服务器应用程序监听UNIX套接字,和Nginx作为反向代理。

现在我希望Nginx等到我的应用上线时,例如,我部署一个更新并重新启动它,而不返回任何错误给客户端。

这是我在Nginx配置中的内容:

location / {
#   proxy_pass http://localhost:8080;
proxy_pass http://unix:/tmp/MyApp.sock;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 60;
}

然而,每当我的应用程序关闭Nginx返回502 Bad Gateway立即。显然proxy_*_timeout设置没有帮助。

本地TCP套接字也是如此。对于UNIX套接字,当我关闭应用程序时,我确保套接字文件被删除,以便Nginx可以看到没有应用程序在运行。

我如何告诉它实际等待一段时间,直到套接字可用?

我不认为核心nginx有这样的功能。然而,使用nginx-lua模块也可以实现类似的功能。即使使用该模块不适合你,我也会在这里发布工作示例,以防它会帮助其他人。

error_page 502 = @error_502;
location / {
proxy_pass http://localhost:8080;
...
}
location = /heartbeat {
internal;
proxy_pass http://localhost:8080;
}
location @error_502 {
rewrite_by_lua_block {
local timeout = 10
local uri = ngx.var.uri
local args = ngx.var.args
local res = { status = 0 }
while timeout > 0 do
ngx.sleep(1)
res = ngx.location.capture("/heartbeat")
if res.status == 200 then break end
timeout = timeout - 1
end
if res.status == 200 then
ngx.exec(uri, args)
end
}
access_by_lua_block {
ngx.status = ngx.HTTP_SERVICE_UNAVAILABLE
ngx.say("I'd waited too long... exiting.")
ngx.exit(ngx.OK)
}
}

这段代码应该非常直接地要求任何额外的注释。这里使用的ngx.sleep是非阻塞的,并且以微秒粒度接受其参数。您的应用程序应该能够处理/heartbeat路由,以便使用它(可能消耗尽可能少的处理时间)。我相信这也可以适应使用UNIX套接字(也许你需要将你的上游定义移动到单独的upstream块)。

重要的注意。由于此解决方案依赖于ngx.location.capture来发出子请求,因此由于此限制,它与HTTP/2协议不兼容(如果需要,请阅读整个讨论以找出可能的解决方案)。

我不会称之为解决方案,但有一种方法可以通过resolver实现这一点。你需要一个DNS,docker会带来一个,但在你的情况下,你需要在你自己的服务器上设置。

server
{
resolver 127.0.0.11 valid=120s; #DNS-IP
resolver_timeout 60; # Timeout for resolver response
}
location / {
set $upstream_service URI; #URI= DNS-Name:Port
proxy_pass http://$upstream_service;
}

所以nginx不能检查服务的可用性并询问解析器。解析器的答案一直等待到超时。如果在超时时间502内没有应答,如果服务在此时间内返回,它将应答,nginx将响应200。

但我不知道它是否与袜子一起工作。

最新更新