记录一次nginx重试机制的踩坑(一般出现不了)

简介: 记录一次nginx重试机制的踩坑

一、问题的产生

最近这几天公司的一个线上的系统出现了故障,操作人员导入了一份excel后,由于处理时间比较长,前端界面一直显示在loading,等到最后就报“接口不可用“了,然后后台的开发人员去查询数据库,发现生成了多条的导入处理任务,这时候,后台、前端、运维人员开始争吵了,各说不是我的问题,最后问题推给了“中间件”。

image.png

二、分析问题

1、 系统现状

既然要分析问题,那先要了解这个系统的部署及网络的情况,从用户操作到服务器的过程。来看下这个系统的部署图,这个图是主要的部分,次要的部分就没画出来了。大致情况就是,用户在网页上操作,数据通过网络传递回服务端,这个过程使用了CDN,然后到负载器,在分发到nginx,nginx在分发到后端的服务上,在到数据库。

image.png

另外,这是一个前后端分离的项目,前端采用Vue开发,后台采用java开发,数据库用mysql。

2、 排查问题

后台写入数据重复,后端的开发一想就是前端重复提交的问题,找前端的同事看,前端说我没有问题呀,操作上还加了loading,用户不可能点第二次,后端开发还是不信,那就打开F12吧,我靠,没有重复的网络请求。

image.png

后端开发找到运维人员,运维说服务器我没动过呀,还是原来那样子。一堆人讨论了半天,有的说是CDN,有的说是nginx,各有各的说法。

3、问题超乎想象

看大家都没有头绪,我说来看下nginx的access log吧,通过简单的grep命令,找到接口对应的请求记录,MD,一看吓一跳,一个接口处理要60s?
image.png

找到对应的开发人员询问情况,它说后台处理确实是要超60s的,在问下前端超时是多久,前端说是30s,这里只能说“我服了”。 正常情况下,前端操作的超时要大于后端的超时,不然后端处理完了,就无法返回给到前端了,前端都超时了,用户可能另起操作或者关闭了。(PS:这种任务就应该做成异步,不知当初是怎么设计的)。
在仔细地看下access log,发现同个接口请求之间间隔的时间是差不多的,不像是前端用户手动操作导致,那会是什么问题?
image.png
image.png

脑海里闪现了是不是nginx的重次机制导致的呢,于是打开这个系统对应的location的conf文件,发现这个API对应的location中并未作个性化配置,都是默认配置。隐约记得location中有几个超时的配置项目,用于控制与后端的连接,读取,发送的。

三、解决问题

1、 nginx的超时、重试机制

找到nginx中用于配置location的超时的配置项,一共有三个:

  • proxy_connect_timeout time:与后端/上游服务器建立连接的超时时间,默认为60s。
  • proxy_read_timeout time:设置从后端/上游服务器读取响应的超时时间,默认60s。此超时时间指的是2次成功读操作时间间隔,而不是读取整个响应体的超时时间。如果超时时间内没有任何响应,则Nginx将关闭连接。
  • proxy_send_timeout time:设置往后端/上游服务器发送请求的超时时间,默认60s。此超时时间指的是2次成功读操作时间间隔,而不是读取整个响应体的超时时间。如果超时时间内没有任何响应,则Nginx将关闭连接。

失败重试机制设置

  • proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | non_idempotent | off ... :配置什么情况下需要向上游服务器进行重试。默认为:error timeout。error表示读写出错;timeout表示超时;invalid_header表示头信息有误;non_idempotent表示RFC-2616定义的非幂等HTTP方法(POST、LOCK、PATCH),也可以在失败后重试(默认幂等方法GET、HEAD、PUT、DELETE、OPTIONS、TRACE);off表示禁用重试。
  • proxy_next_upstream_tries number:设置重试次数,默认0表示不限制。这里的次数包含第一次请求。
  • proxy_next_upstream_timeout time:设置重试最大超时时间,默认0表示不限制。

上面2个值的关系是且的关系,在限制时间内或者重试次数达到一个值就会结束重试,并返回客户端响应。

2、 结合现状分析

从官方的文档中发现:指令 proxy_connect_timeout 或 proxy_read_timeout 为超时状态时,都会触发 proxy_next_upstream 的 timeout 条件,当条件成立时,就会执行proxy_next_upstream_tries中配置的重试次数。

再来看下当前的nginx,location中都是默认值,而后端服务的处理时长却超过60s,这里已经达到触发proxy_next_upstream的条件,请求自动进入重试,从而导致后端服务处理了多次请求,写入了重复的记录。

3、 解决当前问题

既然已经确定问题,那调整相关的参数,在location中加入上面的几个参数,并调整下时长,如下示例。

location /xxx {
   
   
 proxy_connect_timeout 5s;
 proxy_read_timeout 100s;
 proxy_send_timeout 70s;
 proxy_next_upstream error timeout;
 proxy_next_upstream_timeout 70;
 proxy_next_upstream_tries 1;
 proxy_pass http://backend_server;
 add_header upstream_addr $upstream_addr;
 }

重新reload下nginx的配置,让用户在重新操作一次,虽然界面还是在loading,但观察数据库中的记录,已经没有重复写入了,并且前端响应也变快了。

至些问题解决。

四、总结

虽然解决了问题,但好像高兴不起来,MD,处理要超过60s,这是什么概念,要求开发排查到底是那里慢。如果确实是要这么久,要做成异步来处理,不能这样一直loading,体验不好。
image.png

另外,这是通过中间件来解决重复的问题,其实这个说白了,是接口幂等性的问题,应该采用幂等性的处理规则来解决。比如在前端的请求加上一个唯一标识,后台通过对标识的加锁,或者数据库唯一主键、或者文件的MD5码等来解决。

目录
相关文章
|
负载均衡 应用服务中间件 nginx
Nginx之upstream被动式重试机制解读z
Nginx之upstream被动式重试机制解读z
|
弹性计算 负载均衡 应用服务中间件
Nginx重试机制,浏览器重复请求两次多次
问题找到了,原因是Nginx配置文件中,超时时间太短了:proxy_connect_timeout 20;;在Nginx的默认配置是:在客户端请求服务器超时的情况下,Nginx会自动转发该请求到另外一台服务器上,这是Nginx的一种容错机制,所以Nginx的访问日志中会出现同一条请求而两台服务器都执行了一遍的情况,这样以来,程序如果没有做幂等性操作的话数据库会出现两条记录。
1416 0
|
1月前
|
缓存 应用服务中间件 网络安全
Nginx中配置HTTP2协议的方法
Nginx中配置HTTP2协议的方法
82 7
|
2月前
|
应用服务中间件 BI nginx
Nginx的location配置详解
【10月更文挑战第16天】Nginx的location配置详解
|
2月前
|
缓存 负载均衡 安全
Nginx常用基本配置总结:从入门到实战的全方位指南
Nginx常用基本配置总结:从入门到实战的全方位指南
332 0
|
6天前
|
存储 应用服务中间件 nginx
nginx反向代理bucket目录配置
该配置实现通过Nginx代理访问阿里云OSS存储桶中的图片资源。当用户访问代理域名下的图片URL(如 `http://代理域名/123.png`)时,Nginx会将请求转发到指定的OSS存储桶地址,并重写路径为 `/prod/files/2024/12/12/123.png`。
36 5
|
1月前
|
缓存 负载均衡 算法
如何配置Nginx反向代理以实现负载均衡?
如何配置Nginx反向代理以实现负载均衡?
|
1月前
|
存储 负载均衡 中间件
Nginx反向代理配置详解,图文全面总结,建议收藏
Nginx 是大型架构必备中间件,也是大厂喜欢考察的内容,必知必会。本篇全面详解 Nginx 反向代理及配置,建议收藏。
Nginx反向代理配置详解,图文全面总结,建议收藏
|
21天前
|
负载均衡 前端开发 应用服务中间件
负载均衡指南:Nginx与HAProxy的配置与优化
负载均衡指南:Nginx与HAProxy的配置与优化
41 3
|
1月前
|
应用服务中间件 API nginx
nginx配置反向代理404问题
【10月更文挑战第18天】本文介绍了使用Nginx进行反向代理的配置方法,解决了404错误、跨域问题和302重定向问题。关键配置包括代理路径、请求头设置、跨域头添加以及端口转发设置。通过调整`proxy_set_header`和添加必要的HTTP头,实现了稳定的服务代理和跨域访问。
257 1
nginx配置反向代理404问题