Nginx重试引发Http请求重复执行
1.问题背景
web站点通过Nginx做反向代理,两个tomcat做负载均衡。
web站点有一个群发短信模块,管理员可以填写发送内容,手机号列表。点击发送,后台会执行群发短信操作,在发送结束后,返回发送结果。
在很早之前遇到过,重复发送的问题。最开始以为管理员异常操作,重复点击了发送按钮。因此对前端提交做了限制。在点击发送时,把按钮置为disable,执行完毕拿到返回数据,再置为可用,从前端限制重复提交。
今天突然有同事又使用到了这个模块,分别群发了两批短信(8000条和1600条),前端都提示了操作失败,但自己的手机却分别收到了重复的短信推送。
2.问题分析
首先确认了手机号列表没有重复,也通过浏览器调试确认前端没有发起重复请求。
通过查看两台服务器的日志,确实出现了重复的发送,且发送时间点不在同一时刻。
通过日志,可以估算出,发送一条短信的时间在10毫秒。
也通过日志,查看到了处理超时日志,且发现了规律,重复的请求在不同机器处理且处理间隔时间相差一致
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请求设置不同的超时策略。
另外对于短信群发业务,其实有单独的模块,通过规则管理配置,做离线任务执行。现有保留的群发模块,只是为了应对小规模的业务。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

要让 Tomcat 服务器对外网访问,需要:修改 Tomcat 配置文件,允许外部连接。添加防火墙规则,允许访问 Tomcat 服务器端口。创建 DNS 记录,将域名指向 Tomcat 服务器公有 IP。可选:使用反向代理提升安全性和性能。可选:设置 HTTPS 以提高安全性。

ThinkPHP Framework 的本地运行步骤:下载并解压 ThinkPHP Framework 到本地目录。创建虚拟主机(可选),指向 ThinkPHP 根目录。配置数据库连接参数。启动 Web 服务器。初始化 ThinkPHP 应用程序。访问 ThinkPHP 应用程序 URL 运行。

要解决 "Welcome to nginx!" 错误,需要检查虚拟主机配置,启用虚拟主机,重新加载 Nginx,如果无法找到虚拟主机配置文件,则创建默认页面并重新加载 Nginx,这样错误消息将消失,网站将正常显示。

要将 HTML 文件转换为网址,需要使用网络服务器,包括以下步骤:获取网络服务器。设置网络服务器。上传 HTML 文件。创建域名。路由请求。

Node.js 项目的服务器部署步骤:准备部署环境:获取服务器访问权限、安装 Node.js、设置 Git 存储库。构建应用程序:使用 npm run build 生成可部署代码和依赖项。上传代码到服务器:通过 Git 或文件传输协议。安装依赖项:SSH 登录服务器并使用 npm install 安装应用程序依赖项。启动应用程序:使用 node index.js 等命令启动应用程序,或使用 pm2 等进程管理器。配置反向代理(可选):使用 Nginx 或 Apache 等反向代理路由流量到应用程

Dockerfile 中最常用的指令有:FROM:创建新镜像或派生新镜像RUN:执行命令(安装软件、配置系统)COPY:复制本地文件到镜像ADD:类似 COPY,可自动解压缩 tar 存档或获取 URL 文件CMD:指定容器启动时的命令EXPOSE:声明容器监听端口(但不公开)ENV:设置环境变量VOLUME:挂载主机目录或匿名卷WORKDIR:设置容器中的工作目录ENTRYPOINT:指定容器启动时要执行的可执行文件(类似 CMD,但不可覆盖)

是的,Node.js 可以外网访问。您可以使用以下方法:使用 Cloud Functions 部署函数并公开访问。使用 Express 框架创建路由并定义端点。使用 Nginx 反向代理请求到 Node.js 应用程序。使用 Docker 容器运行 Node.js 应用程序并通过端口映射公开。

要成功部署和维护PHP网站,需要执行以下步骤:选择Web服务器(如Apache或Nginx)安装PHP创建数据库并连接PHP上传代码到服务器设置域名和DNS监控网站维护步骤包括更新PHP和Web服务器、备份网站、监控错误日志和更新内容。
