You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多Gunicorn Worker部署Flask API出现重复请求的原因及解决方法

问题分析与解决方案

先澄清:Gunicorn默认逻辑下不会重复分发请求

Gunicorn的master进程负责监听端口、接收请求,然后将请求转发给空闲的worker进程,正常情况下同一个请求只会被一个worker处理。你碰到的重复请求,大概率不是Gunicorn的worker重复处理导致的,更可能来自这些场景:

  • 客户端(比如提交表单的前端、调用方)因为网络波动、超时自动重试
  • 用户多次点击提交按钮,前端触发重复请求
  • 上游有负载均衡/反向代理时,代理因为没收到响应超时,重新转发了请求
  • 你的接口调用第三方API时,第三方返回超时但实际已处理,你这边如果有重试逻辑就会触发重复操作

极端情况下,如果worker处理请求时崩溃,master可能会重新分发请求,但这种情况很少见。

最根本的解决:给接口加幂等性

不管重复请求来自哪里,最可靠的解决方式是让/endpoints/create_parcel接口实现幂等性——也就是同一个请求(或相同业务逻辑的请求)调用多少次,都只会产生一次有效结果。具体可以这么做:

  • 要求客户端传唯一标识:让提交请求的一方携带一个request_id(比如UUID),接口处理前先查这个ID是否已经处理过(存在数据库或Redis里),如果已经处理过,直接返回之前的结果,不再调用第三方API
  • 用业务参数生成唯一键:如果客户端没法传request_id,可以用用户ID、包裹内容哈希、提交时间戳这类参数组合成唯一键,同样先检查键是否存在,避免重复执行
  • 利用第三方API的幂等机制:如果第三方API支持,调用时传他们要求的幂等键(比如idempotency_key),确保重复调用不会重复创建资源

针对Gunicorn的排查与调整

如果你还是怀疑Gunicorn的问题,可以做这些操作:

  • 查worker超时日志:你设置了--timeout 300,如果请求处理时间接近或超过这个值,worker会被master杀死,master可能会重新分发请求。去看Gunicorn的日志(默认输出到stderr),有没有worker超时重启的记录
  • 换异步worker模式:默认的sync模式在处理阻塞操作(比如调用第三方API)时,worker会被占住。可以试试gevent或eventlet异步模式,减少阻塞导致的请求排队和异常分发:
    # 先安装gevent:pip install gevent
    /home/user/miniconda3/bin/gunicorn --bind 0.0.0.0:5000 --workers 3 --worker-class gevent --timeout 300 --chdir /home/user/app wsgi:app
    
  • 开访问日志排查:启动Gunicorn时加--access-logfile -把访问日志打在控制台,或者指定日志文件,看看同一请求的标识(如果有的话)是不是被多次记录,确认是不是Gunicorn分发了重复请求

其他排查方向

  • 检查前端防抖:确认表单提交有没有做防抖处理,防止用户多点导致重复请求
  • 查反向代理配置:如果用了Nginx之类的代理,看代理的超时和重试设置,比如proxy_next_upstream是不是开了不必要的重试
  • 核对第三方API日志:联系第三方确认他们是不是收到了重复调用,定位请求重复的发起方

内容的提问来源于stack exchange,提问作者Erlend Davidson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:43:21