我们正在使用 nginx 来平衡应用程序的请求负载。我们发现,当请求超时时,nginx 会切换到不同的上游服务器(很好)。但是,它对 PUT 和 POST 请求执行此操作,这可能会导致不良结果(数据存储两次)。是否可以将 nginx 配置为仅在超时时重试 GET 请求?或者还有其他方法可以解决问题?
我们的配置如下:
upstream mash {
ip_hash;
server 127.0.0.1:8081;
server 192.168.0.11:8081;
}
server {
...
location / {
proxy_pass http://mash/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
答案1
从 nginx 开始1.9.13,默认情况下不会重试非幂等请求(PUT
、POST
等)。如果您可以升级到此版本或更高版本,则可以默认获得所需的行为。
如果由于某种原因您想要在 1.9.13 或更高版本上继续重试PUT
、POST
等(非幂等)请求,请使用:
proxy_next_upstream error timeout non_idempotent;
答案2
我知道我参与这个游戏已经很晚了,但是对我来说,这是搜索此问题时的最佳结果,所以我想分享我的解决方案。
upstream backend {
server backend1;
server backend2;
}
server {
server_name proxy;
location / {
error_page 598 = @retry;
error_page 599 = @no_retry;
if ($request_method = POST) {
return 599;
}
return 598;
}
location @retry {
proxy_pass http://backend;
}
location @no_retry {
proxy_pass http://backend;
proxy_next_upstream off;
}
}
答案3
答案4
我的 tomcat 服务器也遇到了同样的问题。当出现长请求时,代理会超时。我通过使用 proxy_read_timeout 解决了这个问题。当增加超时时间时,我的请求永远不会超时,也不会出现任何问题。默认超时时间为 60 秒。参考
location / {
proxy_pass http://xxxxxxxxxx.com;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
proxy_connect_timeout 800;
proxy_send_timeout 800;
proxy_read_timeout 240;
}