nginx proxy_next_upstream 与openresty balancer.set_more_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的邮件群组里作出过解释

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的使用的更多相关文章
- Nginx插件之openresty反向代理和日志滚动配置案例
Nginx插件之openresty反向代理和日志滚动配置案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.openresty介绍 1>.Nginx介绍 Nginx是一款 ...
- 接入层高性能缓存技术nginx+redis利器OpenResty
一. OpenRestyOpenResty是一个基于 Nginx与 Lua的高性能 Web平台,其内部集成了大量精良的 Lua库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极 ...
- 关于nginx proxy_next_upstream 重试 和 max_fails的那些事
背景及简要分析 前几天一次故障定位的时候发现,后端服务(java)在从故障中恢复之后,会出现大量499,且会持续较长时间无法自行恢复.根本原因是服务容量问题,处理太慢导致客户端等不了了,主动断开.不过 ...
- 使用SkyWalking监控nginx (以openresty为例)
安装使用SkyWalking先看这篇文章,地址:https://www.cnblogs.com/sanduzxcvbnm/p/15829781.html 使用SkyWalking监控nginx借助的是 ...
- Nginx+lua+openresty精简系列
1. CentOS系统安装openresty 你可以在你的 CentOS 系统中添加 openresty 仓库,这样就可以便于未来安装或更新我们的软件包(通过 yum update 命令).运行下面的 ...
- OpenResty(nginx+lua) 入门
OpenResty 官网:http://openresty.org/ OpenResty 是一个nginx和它的各种三方模块的一个打包而成的软件平台.最重要的一点是它将lua/luajit打包了进来, ...
- openresty nginx 安装过程记录
转载请注明原始地址 http://www.cnblogs.com/dongxiao-yang/p/4877799.html 一 :系统版本 1 cat /etc/issue: CentOS relea ...
- (转)OpenResty(nginx+lua) 开发入门
原文:https://blog.csdn.net/enweitech/article/details/78519398 OpenResty 官网:http://openresty.org/ Open ...
- OpenResty全功能Web应用服务器,打包了标准的 nginx 核心
OpenResty打包了标准的 nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项. 通过揉和众多设计良好的 nginx 模块,OpenResty 有效地把 nginx 服务器转变为一个 ...
随机推荐
- JSON.stringify()的用法
**JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串,而我们一般只是用了第一个参数,没有在意过第二个以及第三个参数的妙用** **1.最常用的方式:** ...
- 寻找写代码感觉(一)之使用 Spring Boot 快速搭建项目
写在前面 现在已经是八月份了,我已经荒废了半年居多,不得不说谈恋爱确实是个麻烦的事,谈好了皆大欢喜,分手了就是萎靡不振,需要很长一段时间才能缓过来. 人还是要有梦想的,至于实现只不过是一个契机,但凡不 ...
- .NET 6 全新指标 System.Diagnostics.Metrics 介绍
前言 工友们, .NET 6 Preview 7 已经在8月10号发布了, 除了众多的功能更新和性能改进之外, 在 preview 7 版本中, 也新增了全新的指标API, System.Diagno ...
- gdb调试用命令与一般调试方法
示例代码 1 #include <iostream> 2 using namespace std; 3 4 void Print() 5 { 6 cout<<"hel ...
- jQuery中的筛选(六):first()、last()、has()、is()、find()、siblings()等
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...
- BeanUtils低依赖属性拷贝测试(一)
javabean package entity; import java.util.Date; /** * 一个测试用: * student,javaBean * @author mzy * 一个标准 ...
- 源码解析.Net中DependencyInjection的实现
前言 笔者的这篇文章和上篇文章思路一样,不注重依赖注入的使用方法,更加注重源码的实现,我尽量的表达清楚内容,让读者能够真正的学到东西.如果有不太清楚依赖注入是什么或怎么在.Net项目中使用的话,请点击 ...
- for in和for of的简单区别
//for in可以遍历数组和对象,但是for of只能遍历数组,不可以遍历对象 var arr = [1,4,5,6,7,8]; var obj = { name:'za', age:19, say ...
- 浅谈Java和Go的程序退出
前言 今天在开发中对Java程序的退出产生了困惑,因为题主之前写过一段时间Go,这两者的程序退出逻辑是不同的,下面首先给出结论,再通过简单的例子来介绍. 对于Java程序,Main线程退出,如果当前存 ...
- MySQL 5.7新特性介绍
本文是基于MySQL-5.7.7-rc版本,未来可能 还会发生更多变化. 1.即将删除的特性1.1.InnoDB monitoring features,详见:WL#7377(访问地址:http:// ...