nginx proxy_next_upstream 与 openresty balancer.set_more_tries 的使用
背景
我们这边网关服务使用的 kong,前段时间上线一个服务,这个服务它报错了,产生了 502 的错误码,追查这个报错的时候发现了网关服务的两个可疑的地方,第一个疑点是我们在 Kong 上配置的 Retries = 5,但是实际实际上我们的代理重试至多只会重试三次。第二个疑点是我们的重试只重试了 502 和 504,大量的 500 错误没有重试。带着这两个问题了查了下 kong 和 openresty 代码。
结论
首先给出问题的结论第一个问题 Kong 上配置的 Retries = 5,但是实际上只会重试三次。出现这个问题的原因是因为我们在 nginx 上有一行配置
当我们在基于 openresty Kong 上做 balancer.set_more_tries(5) 这个操作的时候 nginx 会基于保护措施启用 nginx 的配置 proxy_next_upstream_tries,所以 proxy 重试的时候最多只能重试三次。
第二个问题,就是为什么只有 502 504 作出了重试,而且 500 没有做重试这个的原因也是因为我们在 nginx 的配置里面有这么一行配置
只需要加上 http_500 500 的错误码就可以重试了。
问题的定位
先说一下第一个问题的定位过程主要是不知道有 nginx 有 proxy_next_upstream_tries 这个参数,一直以为是 openresty balancer.set_more_tries 控制的重试次数,一度自以为是的觉得这是 bug,都想提个 issues,直到在 openresty 的群组邮件里面春哥有一个关于这个问题的回复。这个问题春哥在 openresty 的邮件群组里作出过解释
就看到了 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
其它参数挺简单的,有哪些请求应该被转发到下一个上游服务器。主要是最后一个参数 non_idempotent, 默认情况下一些非幂等的函数(POST, LOCK, PATCH)不会被转发到下一个上游服务器,这个参数会允许此类请求也被转发到下一个上游服务器上。
评论