如果后端关闭,则在短时间内缓冲对 nginx 的请求

Mar*_*rin 8 nginx node.js

我有一个永远运行在 nginx 后面的 nodejs 应用程序。当我部署新代码时,我只是这样做,forever restart但即使在这么短的时间内我也无法获得 502。

如何配置 nginx 以在 502 的情况下继续在这台上游服务器上重试?我尝试设置proxy_connect_timeoutproxy_read_timeout然后proxy_send_timeout例如,30s但无论如何我都会立即得到 502 :(

我的网站配置是:

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;
 }
}
Run Code Online (Sandbox Code Playgroud)

当上游不可用时,是否可以在这么短的时间内缓冲请求?

cns*_*nst 1

这最终听起来像是您的后端的问题:nginx 向您的后端发出请求,连接立即被拒绝,因此,nginx 没有其他选项可以将错误下游传递给用户,因为没有指定其他上游,并且timeout您指定的值在这里不起作用,因为 nginx 根本不需要等待任何事情。


我现在不知道它forever是什么,也不知道它是如何工作的,但我想到了一些可能的解决方案。

上游发生的情况有两种可能性:

  • “永远”可能会接受连接,并立即返回错误。在这种情况下,听起来您真正应该问的是如何使其不误处理连接,而是等到您的应用程序完成部署,然后当场处理请求。 服务器上的应用程序存在此问题。opengroktomcat

  • 没有人在侦听您的应用程序应该运行的端口,因此,内核会立即丢弃数据包,并立即返回 TCP RST 数据包。

    • 如果TCP RST是原因,您可以通过forever保留侦听套接字来解决它,或者通过配置内核将传入数据包排队一段时间,以期待稍后有人拾取它们,以便何时forever启动备份,它'将有一整个队列准备好提供服务。

    • 将内核配置TCP RST为无人监听时不发出,那么你的timeoutnginx就会生效。随后,配置nginx向另一个上游发出第二个请求。

如果您解决了上述任一情况,那么您就完成了。

否则,您必须尝试配置 nginx 来解决该问题:

  • 你可以尝试proxy_cacheproxy_cache_use_stale.

  • 您可以尝试使用错误处理程序:see proxy_intercept_errors(可能仅适用于您收到的 503 是从后端传递的)和error_page。您可能希望在错误处理程序中浪费时间,直到您的应用程序重新启动,然后向您的应用程序发出请求。

    • 您可能会浪费时间运行第二个应用程序,该应用程序只会执行sleep()重新部署应用程序所需的时间,然后提供 HTTP 重定向,或者在没有响应的情况下退出;哎呀,你可以简单地通过尝试代理到防火墙中的 TCP 端口来实现这一点block drop,这将激活 nginx 中的超时。随后,配置 nginx 发出第二个请求。

如果您实施上述涉及激活的方法之一timeout,那么随后将需要向后端发出额外的请求。您可以使用upstream该指令,您可以多次指定同一服务器,或者如果不接受,可以通过防火墙镜像端口,或者更好的是,您实际上可以首先运行多个独立的应用程序服务器。

这让我们回到你的应用程序服务器:如果它无法处理干净的重新部署问题,那么也许你应该运行两个这样的应用程序服务器,并使用 nginx 在它们之间进行负载平衡。或者重新部署它们,然后在实际准备好后将 nginx 切换到新副本。否则,您怎么可能确定您的客户愿意等待 30 秒来让您的 API 响应?