我想问一下有关 Nginx 请求重试的问题。我在后端运行一个 Nginx,然后将请求发送到 HaProxy,然后 HaProxy 将其传递到 Web 服务器并处理该请求。我正在动态重新加载我的 Haproxy 配置以提供弹性。问题是当我重新加载 Haproxy 时请求会被丢弃。所以我希望有一个解决方案,我可以从 Nginx 重试该请求。我查看了 http 模块中的 proxy_connect_timeout、proxy_next_upstream 以及服务器模块中的 max_fails 和 fail_timeout。我最初在上游连接中只有 1 个服务器,所以我现在只启动了两次,并且丢弃的请求更少了(仅当)在上游有两次相同的服务器时,如果我有相同的服务器,丢弃的次数会增加 3-4 次。
因此,首先我想的是,当请求无法从 Nginx 到 Haproxy 建立连接时,重新加载时似乎连接被视为错误,并且请求立即被丢弃。
那么我该如何指定失败后的时间我想从 Nginx 重试请求到上游或者 Nginx 将其视为失败请求的时间之前的时间。
(我尝试增加 proxy_connect_timeout - 没有帮助,mail_retires,fail_timeout 以及两次放置相同的上游服务器(到目前为止给出了最好的结果)
Nginx 配置文件
上游 gae_sleep {
server 128.111.55.219:10000;
}
服务器 {
listen 8080;
server_name 128.111.55.219;
root /var/apps/sleep/app;
# Uncomment these lines to enable logging, and comment out the following two
#access_log /var/log/nginx/sleep.access.log upstream;
error_log /var/log/nginx/sleep.error.log;
access_log off;
#error_log /dev/null crit;
rewrite_log off;
error_page 404 = /404.html;
set $cache_dir /var/apps/sleep/cache;
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_redirect off;
proxy_pass http://gae_sleep;
client_max_body_size 2G;
proxy_connect_timeout 30;
client_body_timeout 30;
proxy_read_timeout 30;
}
location /404.html {
root /var/apps/sleep;
}
location /reserved-channel-appscale-path {
proxy_buffering off;
tcp_nodelay on;
keepalive_timeout 55;
proxy_pass http://128.111.55.219:5280/http-bind;
}
}
答案1
因此,在尝试找到 nginx 重试请求的答案后,我还没有找到一种干净的重试请求的方法,但想出了一种 hacky 方法。因此在上游nginx conf 中的部分,您应该放置同一上游服务器的多个副本,因为 nginx 中的重试是在上游服务器级别进行的。如果一个上游服务器发生故障,则 nginx 会在另一个上游服务器上尝试该请求。如果您只有 1 个上游服务器(就像我一样),它就不会重试该请求。因此,为了克服这个问题,我放置了同一上游服务器的多个副本,这样当 nginx 浏览服务器列表并发送请求时,上游服务器(在本例中为 haproxy)将重新加载并且请求将转到。同样重要的是,了解 nginx 在 http 模块和服务器模块中提供的各种超时。 “fail_timeout” - 表示如果上游服务器不可用,则将其停用 x 秒,但如果所有服务器都不可用,则不会停用(我提到这一点是因为当 nginx 遍历整个列表时,haproxy 可能还没有出现,但由于此属性,这不会成为问题)PS:这是一个 hacky 解决方案,我必须在我的 nginx 文件中有 100-150 个上游条目,以将错误减少到显着数量。欢迎更好的解决方案 :)
答案2
这不是您要问的,但可能更切题:您如何重新启动 HAProxy?使用 SF 选项,您应该能够重新启动 HAProxy 而不会丢弃任何连接请求。我不相信 nginx 可以重试请求,但如果您真的想要,您可以将 HAProxy 前端连接到另一个 HAProxy 实例。然后 HAProxy 会重试对第二个实例的请求。但这似乎真的很愚蠢。首先查看 SF 选项。
重新启动 HAProxy 脚本(来自评论)greps 只是为了让我感到温暖模糊的感觉:
#!/bin/sh
ps -ef | grep haproxy
haproxy -f haproxy.cfg -sf $(cat /var/run/haproxy.pid)
ps -ef | grep haproxy