nginx proxy_next_upstream 与openresty balancer.set_more_tries的使用

摘要:
出现这个问题的原因是因为我们在nginx上有一行配置proxy_next_upstream_tries3;当我们在基于openrestyKong上做balancer.set_more_tries这个操作的时候nginx会基于保护措施启用nginx的配置proxy_next_upstream_tries,所以proxy重试的时候最多只能重试三次。问题的定位先说一下第一个问题的定位过程主要是不知道有nginx有proxy_next_upstream_tries这个参数,一直以为是openrestybalancer.set_more_tries控制的重试次数,一度自以为是的觉得这是bug,都想提个issues,直到在openresty的群组邮件里面春哥有一个关于这个问题的回复。Regards,-agentzh就看到了proxy_next_upstream_tries配置,以及互斥的时候以哪个为准。

背景

我们这边网关服务使用的 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的邮件群组里作出过解释
https://img2020.cnblogs.com/blog/1557931/202109/1557931-20210921064201910-2122530166.jpg

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:

error
an error occurred while establishing a connection with the server, passing a request to it, or reading the response header;
timeout
a timeout has occurred while establishing a connection with the server, passing a request to it, or reading the response header;
invalid_header
a server returned an empty or invalid response;
http_500
a server returned a response with the code 500;
http_502
a server returned a response with the code 502;
....
non_idempotent
normally, 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)不会被转发到下一个上游服务器,这个参数会允许此类请求也被转发到下一个上游服务器上。

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

免责声明:文章转载自《nginx proxy_next_upstream 与openresty balancer.set_more_tries的使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SerializeField和Serializable模块三 GO语言实战与应用-bytes包与字节串操作(上)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

BGP 下一跳的理解和实验

下一跳 路由器将BGP路由更新给ibgp邻居,下一跳默认是不变的,可以通过next-hop-self修改 路由器将bgp路由更新给ebgp邻居,下一跳自动更新为本路由器的更新源地址 第三方下一跳(重定向) r1#traceroute 4.4.4.4                                                      ...

vue中记录页面的滚动距离

业务需求:pageOne页面是一个商品列表页面,在这个页面点击商品,就会跳转到pageTwo商品详细页面。此时再从pageTwo页面返回到pageOne页面时,pageOne页面需要做到:1.记录pageOne之前的滚动的距离。2.不重新请求数据。而从其它页面进入到pageOne页面时,pageOne页面不需要记录之前的滚动距离和需要重新请求数据。 1.使...

《深度剖析CPython解释器》29. Python内存管理与垃圾回收(第二部分):源码解密Python中的垃圾回收机制

楔子 现在绝大部分的语言都实现了垃圾回收机制,这其中也包括Python,而不同的语言采用的垃圾回收算法也各不相同。那么,常见的垃圾回收算法都有哪些呢? 引用计数法(reference count): 记录对象的被引用此处, 引用计数降为0时回收 标记-清除法(mark-sweep): 从根集合触发, 遍历所有能访问到的对象并对其进行标记, 然后将未被标记...

数据结构之线性表的链式存储结构

一、基本概念 链式存储 :用一组任意的存储单元存储线性表中的数据元素。用这种方法存储的线性表简称线性链表。存储链表中结点的一组任意的存储单元可以 是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上的。 为了正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其直接后继结点的地址(或位置),称为指针(pointer)或链(link),...

apache2.2安装和配置(安装版)

apache2.2安装和配置(安装版) 1.         Next→Iaccept,Next→在Network Domain下填入你的域名,在Server Name下填入你的服务器名称(也就是主机名加上域名),在Administrator's Email Address下填入系统管理员的联系电子邮件地址,选forAllUser,Next→选Custo...

HashMap源码和并发异常问题分析

要点源码分析 HashMap允许键值对为null;HashTable则不允许,会报空指针异常; HashMap<String, String> map= new HashMap<>(2); map.put(null,null); map.put("1",null); Hash...