写点什么

nginx proxy_next_upstream 与 openresty balancer.set_more_tries 的使用

作者:飞翔
  • 2022 年 4 月 22 日
  • 本文字数:1662 字

    阅读完需:约 5 分钟

背景

我们这边网关服务使用的 kong,前段时间上线一个服务,这个服务它报错了,产生了 502 的错误码,追查这个报错的时候发现了网关服务的两个可疑的地方,第一个疑点是我们在 Kong 上配置的 Retries = 5,但是实际实际上我们的代理重试至多只会重试三次。第二个疑点是我们的重试只重试了 502 和 504,大量的 500 错误没有重试。带着这两个问题了查了下 kong 和 openresty 代码。

结论

首先给出问题的结论第一个问题 Kong 上配置的 Retries = 5,但是实际上只会重试三次。出现这个问题的原因是因为我们在 nginx 上有一行配置


proxy_next_upstream_tries 3;
复制代码


当我们在基于 openresty Kong 上做 balancer.set_more_tries(5) 这个操作的时候 nginx 会基于保护措施启用 nginx 的配置 proxy_next_upstream_tries,所以 proxy 重试的时候最多只能重试三次。


第二个问题,就是为什么只有 502 504 作出了重试,而且 500 没有做重试这个的原因也是因为我们在 nginx 的配置里面有这么一行配置


proxy_next_upstream error timeout http_502 http_504 non_idempotent;
复制代码


只需要加上 http_500 500 的错误码就可以重试了。

问题的定位

先说一下第一个问题的定位过程主要是不知道有 nginx 有 proxy_next_upstream_tries 这个参数,一直以为是 openresty balancer.set_more_tries 控制的重试次数,一度自以为是的觉得这是 bug,都想提个 issues,直到在 openresty 的群组邮件里面春哥有一个关于这个问题的回复。这个问题春哥在 openresty 的邮件群组里作出过解释



Hello!
2015-11-19 18:52 GMT+08:00 DeJiang Zhu:>> > - 在 `proxy_next_upstream_tries 0;` 的时候, set_more_tries 好像没有效果了.>> 我测试了也是这样> 然后看了代码发现: set_more_tries 并不能超过 proxy_next_upstream_tries 的配置 [1]
这是故意的,proxy_next_upstream_tries 规定的是重试上限。这可以避免 Lua 代码逻辑上的错误而导致无休止的重试。
Regards,-agentzh
复制代码


就看到了 proxy_next_upstream_tries 配置,以及互斥的时候以哪个为准。


第二个问题,上游 500 的错误码没有被重试。这个问题的定位主要是陷入了以前引入 Kong 的一个误区了,我们的服务引入 Kong 的其中一个原因就是有些服务重启中发生错误的不能将服务重试到没有问题的上游服务器上去(其实主要是 nginx 不能按照我们的预想重试到上游服务上)。所以一直以为这是 Kong 的问题,所以把 Kong 的 Kong init 中关于 Kong.balancer()的方法看了很长时间,测试了好多次,才确定不是这里问题,后来又去看了下 Passive health checks 被动健康检查代码,以为是这里做了重试,上游服务区的列表轮训引起的,最后也确定了跟这里没有关系。


最后一个一个过 proxy_XXX 的方法的时候,发现了 proxy_next_upstream 的配置说明,这个函数其实手册将的特别清楚http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream


Specifies in which cases a request should be passed to the next server:
erroran error occurred while establishing a connection with the server, passing a request to it, or reading the response header;timeouta timeout has occurred while establishing a connection with the server, passing a request to it, or reading the response header;invalid_headera server returned an empty or invalid response;http_500a server returned a response with the code 500;http_502a server returned a response with the code 502;....non_idempotentnormally, requests with a non-idempotent method (POST, LOCK, PATCH) are not passed to the next server if a request has been sent to an upstream server (1.9.13); enabling this option explicitly allows retrying such requests;
复制代码


其它参数挺简单的,有哪些请求应该被转发到下一个上游服务器。主要是最后一个参数 non_idempotent, 默认情况下一些非幂等的函数(POST, LOCK, PATCH)不会被转发到下一个上游服务器,这个参数会允许此类请求也被转发到下一个上游服务器上。

还是应该多研究书册,仔细看说明

用户头像

飞翔

关注

是多福多寿 2017.08.31 加入

awsf首都发生大

评论

发布
暂无评论
nginx proxy_next_upstream 与openresty balancer.set_more_tries的使用_nginx_飞翔_InfoQ写作社区