负载均衡超时重发HTTP请求

58 篇文章 0 订阅
1 篇文章 0 订阅

一个线上紧急问题,有意思做了些测试和记录

背景描述:新上线一个比较复杂的批量功能,一次请求后台方法跑个2,3个小时不成问题,方法代码大致模式就是查询出表A中还没有处理的数据,循环数据集,对每行数据一番操作后保存到表B中,并标记表A本条数据已处理,事务每行一提交。

问题现象:表B中数据重复,有不重复的,有重复一次的,有重复两次及以上的

排查前猜想这数据样子肯定是重复请求,代码操作的时候没锁表A,一次请求执行了一半,又来了个请求,第二个请求查询当前还没处理的数据,这部分数据就会重复两次,再第三个第四个请求来,导致重复两次以上。代码确实有问题,没锁表,但是想肯定是用户开了多个功能做重复了啊,赖到用户身上先~

但是用户表情严肃:没人动,自始至终我只点了一下

懵圈,woc点了一下也会重复,http重发?我本地debug 一停就是一上午也没见重发请求啊,自己在生产环境试了一下,还真重复,过一段时间就会收到一个重复的http请求,因为是集群环境,所以怀疑是负载问题,带着发现找硬件F5,捣鼓好久发现F5超时参数配置的时长和重复请求间隔吻合,调长超时时间,问题解决。

F5我是没研究,也没接触过,我用nginx还原一下情况

Nginx重发请求测试

两台电脑,两个tomcat在一台,一个nginx在另一台

项目代码

RestController  Get请求,睡眠30秒模拟业务耗时

两个tomcat上都部署的是这个程序,访问路径  /demo/testGet

Nginx配置

上边测试代码设置的超时为30s,nginx配置的超时就该比30s小,保证nginx超时重试时,代码还卡着

  • keepalive_timeout  65;            与客户端keepalive的超时时间
  • proxy_read_timeout 20;          与被代理的服务器 读超时时间,20s没有收到服务器发来的响应数据,nginx就断开
  • proxy_send_timeout 20;          与被代理的服务器 写超时时间,20s没有发给服务器数据,nginx断开
  • proxy_next_upstream error timeout;    nginx失败重发机制的核心参数, 在error或者超时情况下,将请求传递给下一个服务器,可以自定义,例如可以设置服务器返回某个状态码的情况下传递

测试GET

在nginx那台电脑上用浏览器发起请求http://localhost:9258/demo/testGet

确实发现请求在两台tomcat上都来了一次,间隔20s

 通过wireshark抓包也发现,两次HTTP,第一次请求和8080端口三次握手,过了20s,nginx发起FIN关闭socket,并与另一tomcat也就是8010端口三次握手建立连接并发起新的HTTP请求

 测试POST

同样准备了一个Post方法,还是nginx那台电脑postman走一下http://localhost:9258/demo/testPost

 不一样了,post只发了一次

 度了度之后,知道nginx默认只会对幂等的http方法进行重发,幂等的例如(GET/DELETE/PUT),而POST是非幂等的,所以默认不会重发

如果业务需要重试post,需要对nginx的proxy_next_upstream参数追加non_idempotent,如下

proxy_next_upstream error timeout non_idempotent;

 修改参数,nginx -s reload,再次发起post请求,可以看到与Get流程相同,新的http连接到8010端口

控制台都有输出

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值