nginx反向HTTP代理 - 所有上游不可用时的行为是什么?

时间:2018-02-21 19:39:00

标签: nginx reverse-proxy tcp-ip

在尝试测量和增加我们的nginx吞吐量时,我注意到可能是我们配置的问题,但我不确定如何测试它。

我们使用简单的上游配置,有点像这样:

upstream myapp1 {
    server srv1.example.com max_fails=1 fail_timeout=3s;
    server srv2.example.com max_fails=1 fail_timeout=3s;
    server srv3.example.com max_fails=1 fail_timeout=3s;
}

当我们的后端变得过载时,第一个上游可能会进入不可用状态,并且添加的负载可能会很快导致其他后端失败,并且在fail_timeout设置的持续时间内没有可用的后端。

nginx在这种情况下如何表现?它如何处理传入的客户端连接?我可以在nginx日志中看到哪些错误?

从OS / netstat监控,似乎nginx尝试缓存这些传入连接,直到一个或多个后端返回可用状态,此时......我不确定。是否所有等待的连接都被转储到第一个可用的后端,可能导致另一个过载的服务,以及重复失败的循环?

在这种情况下,正确的行为是什么,可以(应该?)nginx配置为在没有后端可用时简单地丢弃/ 503任何传入连接?

更新:经过进一步研究,似乎nginx将根据各种设置决定后端是否可用。忽略这些设置,有没有办法观察nginx的决定?也许是日志条目?什么东西来确认引擎盖下发生了什么?

2 个答案:

答案 0 :(得分:1)

没有"正确"这种情况下的行为更多地取决于您希望如何处理/管理负载以及您的设置。

请注意,error_page会处理由Nginx生成的错误,因此,如果您希望根据上游的返回状态代码执行操作,则需要proxy_intercept_errors,例如:

location / {
    proxy_pass http://myapp1;
    proxy_http_version 1.1; 
    proxy_redirect off;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;

    proxy_intercept_errors on;
    error_page 500 502 503 504  =200 /50x.html;
}

在这种情况下,行:

error_page 500 502 503 504  =200 /50x.html;

当您的上游返回20050x.html500时,会返回状态代码502并显示503页面的内容或504

答案 1 :(得分:1)

听起来你可能比简单的nginx前端有更深层次的架构问题。

当然,监控前端服务器的性能以及它如何处理后端是很重要的,但是,最好的想法是以避免前端过载的方式构建基础架构。 - 首先结束。

上游方案失败的正常原因是系统重新启动,或者物理基础设施失败,而不是使您的上游之一瘫痪的slashdot流量峰值,并且随后导致多米诺骨牌效应上游也是。

(TBH,如果它是可能导致您的上游之一宕机的名义峰值负荷,那么不清楚是什么让您认为其他人可能会保持在线,无论哪个组合nginx会将剩余的客户端发送给他们,前提是所有客户端的容量大致相等。)

因此,在设计架构时,您需要确保拥有足够数量的上游服务器,其中任何一台服务器都不会导致其余服务器出现过载情况。这意味着每个人都必须拥有合理数量的储备容量,并且如果适用的话,也可以优雅地处理错误。

此外,在前端实现故障排除总是一个好主意 - nginx提供http://nginx.org/r/limit_connhttp://nginx.org/r/limit_req,这些都可以确保过载条件可以在根处被检测到。您可以将其与http://nginx.org/r/error_page结合使用以捕获错误(可能使用http://nginx.org/r/recursive_error_pages和/或http://nginx.org/r/proxy_intercept_errors,如果适用),并根据具体情况提供您网页的缓存版本(请参阅http://nginx.org/r/proxy_cache)或适当的错误消息。即使使用标准语法和标准指令,对nginx的逻辑数量也没有限制;例如,在完全类似微服务的架构中,它可能是detect and handle the slashdot effect directly from within nginx

至于nginx,它在最苛刻的任务关键型应用程序中是经过验证的 - http://nginx.org/r/upstream非常清楚如何进行服务器选择:

  

默认情况下,使用加权循环平衡方法在服务器之间分配请求。 ...如果在与服务器通信期间发生错误,请求将被传递到下一个服务器,依此类推,直到将尝试所有正常运行的服务器。如果无法从任何服务器获得成功的响应,则客户端将收到与最后一个服务器的通信结果。

如果这些条件没有记录在http://nginx.org/r/error_log中,我会感到惊讶,特别是取决于您指定的日志记录级别。如果您的安装非常庞大,您可能还需要研究商业监控解决方案,例如NGINX Amplify