欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  php教程

Nginx重试引发Http请求重复执行

程序员文章站 2022-05-02 08:10:17
...

1.问题背景

web站点通过Nginx做反向代理,两个tomcat做负载均衡。

web站点有一个群发短信模块,管理员可以填写发送内容,手机号列表。点击发送,后台会执行群发短信操作,在发送结束后,返回发送结果。

在很早之前遇到过,重复发送的问题。最开始以为管理员异常操作,重复点击了发送按钮。因此对前端提交做了限制。在点击发送时,把按钮置为disable,执行完毕拿到返回数据,再置为可用,从前端限制重复提交。

今天突然有同事又使用到了这个模块,分别群发了两批短信(8000条和1600条),前端都提示了操作失败,但自己的手机却分别收到了重复的短信推送。

2.问题分析

首先确认了手机号列表没有重复,也通过浏览器调试确认前端没有发起重复请求。

通过查看两台服务器的日志,确实出现了重复的发送,且发送时间点不在同一时刻。

通过日志,可以估算出,发送一条短信的时间在10毫秒。

Nginx重试引发Http请求重复执行

也通过日志,查看到了处理超时日志,且发现了规律,重复的请求在不同机器处理且处理间隔时间相差一致

A日志

10:03:05,878  INFO TIMEOUT.info:252 - time: 75701ms, concurrent: 1, url: 
/push/sendmessage.10:07:24,705  INFO TIMEOUT.info:252 - time: 15148ms, concurrent: 0, url: /push/sendmessage.

B日志

10:03:21,599  INFO TIMEOUT.info:252 - time: 76471ms, concurrent: 1, url: 
/push/sendmessage.10:07:39,718  INFO TIMEOUT.info:252 - time: 15113ms, concurrent: 0, url: /push/sendmessage.

结合以上信息猜测,应该是请求执行时间超过限制,造成前端提示失败。重复的提交应该是重试机制造成。

于是联系运维进行确认。得到相关答复:

Nginx可以配置超时时间,假设配置15s,而一个请求需要16s才能处理完返回。Nginx路由到A服务器处理,A执行到第15s时,没有正常返回,Nginx会重新发到B服务处理,B执行到第15s时,也没有正常返回。前端等待30s,最后返回失败。A和B分别收到对应的请求,内部都进行了处理。

和运维同学确认过原因后,就可以根据相关信息自己搜索。

nginx的重试机制

文中也点到了一种解决方案,可以通过ip访问服务,绕过nginx。

另外我们的web站点,有一个下载的功能,在优化之前,每次下载的执行时间也很长,但是确没有遇到超时问题。分析了可能是GET和POST的区别。上文也给出了下面这个链接,确定大致思路。

http://serverfault.com/questions/528653/how-can-i-stop-nginx-from-retrying-put-or-post-requests-on-upstream-server-timeo

3.问题总结

通过网上的信息参考,Nginx可以对文件上传,下载,GET和POST请求设置不同的超时策略。

另外对于短信群发业务,其实有单独的模块,通过规则管理配置,做离线任务执行。现有保留的群发模块,只是为了应对小规模的业务。

相关标签: Nginx