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 服务器转变为一个 ...
 
随机推荐
- 【死磕 Java 基础】 — 自己动手实现一个 LRU
			
大家好,我是大明哥,一个专注于[死磕 Java]系列创作的男人 个人网站:https://www.cmsblogs.com/.专注于 Java 优质系列文章分享,提供一站式 Java 学习资料 LRU ...
 - Git (10)-- 打标签(git tag)
			
@ 目录 1.列出标签 2.创建标签 2.1.附注标签 2.2.轻量标签 3.后期打标签 4.共享标签 5.删除标签 6.检出标签 超详细 Git 图文版小白教程(持续更新) 像其他版本控制系统(VC ...
 - Pikachu-Unsafe Fileupload模块
			
一.概述 文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像.上传附件等等.当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型.后缀名.大小等等,然后将其按照设 ...
 - miniFTP项目实战五
			
项目简介: 在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务 ...
 - Python实现发送邮件(实现单发/群发邮件验证码)
			
Python smtplib 教程展示了如何使用 smtplib 模块在 Python 中发送电子邮件. 要发送电子邮件,我们使用 Python 开发服务器,Mailtrap 在线服务和共享的网络托管 ...
 - C# WPF 后台调整怎样使用代码把指定控件的Z序调整到最前面呢?
			
Panel.SetZIndex(rectangle1, 2); //把前台名称为rectangle1的矩形的ZIndex设置为2
 - 【springcloud】模拟RPC调用(Feign)
			
转自:https://blog.csdn.net/pengjunlee/article/details/86615408 Feign简介 Feign是一个声明式的Web Service客户端,它能够让 ...
 - Quartz任务调度(1)概念例析快速
			
实例解析概念 在quartz中,有几个核心类和接口:Job.JobDetail.Trigger.Calendar.Scheduler.下面我们结合实例来分析这些类的角色定位.现在我们有一个新闻网站,它 ...
 - 解决maven中静态资源只能放到properties中的问题
			
构建Maven项目的时候,如果没有进行特殊的配置,Maven会按照标准的目录结构查找和处理各种类型文件. Maven项目的标准目录结构 src main java 源文件 resour ...
 - 使用volatile的条件
			
使用volatile的值不能依赖于它之前的值: volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果. ...