背景

我们这边网关服务使用的 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:

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的使用的更多相关文章

  1. Nginx插件之openresty反向代理和日志滚动配置案例

    Nginx插件之openresty反向代理和日志滚动配置案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.openresty介绍 1>.Nginx介绍 Nginx是一款 ...

  2. 接入层高性能缓存技术nginx+redis利器OpenResty

    一. OpenRestyOpenResty是一个基于 Nginx与 Lua的高性能 Web平台,其内部集成了大量精良的 Lua库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极 ...

  3. 关于nginx proxy_next_upstream 重试 和 max_fails的那些事

    背景及简要分析 前几天一次故障定位的时候发现,后端服务(java)在从故障中恢复之后,会出现大量499,且会持续较长时间无法自行恢复.根本原因是服务容量问题,处理太慢导致客户端等不了了,主动断开.不过 ...

  4. 使用SkyWalking监控nginx (以openresty为例)

    安装使用SkyWalking先看这篇文章,地址:https://www.cnblogs.com/sanduzxcvbnm/p/15829781.html 使用SkyWalking监控nginx借助的是 ...

  5. Nginx+lua+openresty精简系列

    1. CentOS系统安装openresty 你可以在你的 CentOS 系统中添加 openresty 仓库,这样就可以便于未来安装或更新我们的软件包(通过 yum update 命令).运行下面的 ...

  6. OpenResty(nginx+lua) 入门

    OpenResty 官网:http://openresty.org/ OpenResty 是一个nginx和它的各种三方模块的一个打包而成的软件平台.最重要的一点是它将lua/luajit打包了进来, ...

  7. openresty nginx 安装过程记录

    转载请注明原始地址 http://www.cnblogs.com/dongxiao-yang/p/4877799.html 一 :系统版本 1 cat /etc/issue: CentOS relea ...

  8. (转)OpenResty(nginx+lua) 开发入门

    原文:https://blog.csdn.net/enweitech/article/details/78519398 OpenResty 官网:http://openresty.org/  Open ...

  9. OpenResty全功能Web应用服务器,打包了标准的 nginx 核心

    OpenResty打包了标准的 nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项. 通过揉和众多设计良好的 nginx 模块,OpenResty 有效地把 nginx 服务器转变为一个 ...

随机推荐

  1. Install Redmine on Virtual Machine with Vagrant

    Initialize VM: chad@typcserver ~/docs/vagrant-prj $ vagrant --version Vagrant 1.4.3 chad@typcserver ...

  2. Mysql5.7.34 数据库源码编译安装

    Mysql 数据库源码编译安装 MySQL是一个关系型数据库管理系统,关系型数据库是将数据保存在不同的表中,而非将所有数据放在一个大仓库内,这样就加快了速度并提高了灵活性.由于其体积小.速度快.总体拥 ...

  3. SQL 练习13

    查询没学过"张三"老师讲授的任一门课程的学生姓名 SELECT * from Student WHERE SId not in ( SELECT SC.SId from Teach ...

  4. Golang在Linux系统中实现微秒级延迟

    在程序中延迟或者等待一段时间一般可以使用Sleep函数实现,但是因为操作系统线程调度的消耗,往往只能做到十几或者数十毫秒的精度,很难达到微秒级,Golang的time.Sleep也是如此. Sleep ...

  5. HBuilder mui 手机app开发 Android手机app开发 ios手机app开发 打开新页面 预加载页面 关闭页面

    创建子页面 在mobile app开发过程中,经常遇到卡头卡尾的页面,此时若使用局部滚动,在android手机上会出现滚动不流畅的问题: mui的解决思路是:将需要滚动的区域通过单独的webview实 ...

  6. SQL server多表联合查询

    参考网址: https://blog.csdn.net/zou15093087438/article/details/79226394 1. 外连接可分为:左连接.右连接.完全外连接. a.  左连接 ...

  7. springboot整合zookeeper实现分布式锁

    目录 01 安装并允许zookeeper 02 springboot应用配置CuratorFramework 03 使用zookeeper实现集群只一个应用实例执行定时任务 04 使用zookeepe ...

  8. WebStorm怎么设置实现自动编译less文件

    首先,需要保证电脑安装过Node.js,下载地址:https://nodejs.org/en/ 安装Node.js的时候会自动安装npm 然后,安装lessc模块 打开cmd控制台 输入下面一行npm ...

  9. C# wpf中DataGrid 支持汇总行

    最近有一个需求,需要汇总金额,份额等字段.我们使用的是原生的WPF控件,自己开发了一套Template.而没有使用比较成熟的第三方控件.所以这个功能得自己开发.并且要做成控件层次的功能. 当然也可以这 ...

  10. jquery validate 如何校验多个相同name

    在表单页中有如下代码 <form> <input name="zhai"/><!-- 三个相同name的input --> <input ...