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

uwsgi响应超时配置问题:如何避免处理已被客户端丢弃的请求

问题根因分析

你当前配置的超时参数未生效、压测100%失败的核心原因如下:

  • 你配置的http-connect-timeout仅作用于TCP三次握手阶段,和请求建立后的处理超时完全无关
  • 你配置的http-timeout是连接空闲超时,仅当连接上无任何数据传输超过阈值才会触发,请求处理过程中连接属于活跃状态,因此不会生效
  • 压测失败是因为你固定了2个单线程worker,每个请求需要4秒处理,满负载下每秒仅能处理0.5个请求,当locust并发超过1后,8长度的监听队列很快被占满,后续请求直接被uwsgi拒绝,导致100%失败
  • 你注释的uwsgi.is_connected判断未生效是因为仅做了单次检测,没有在耗时逻辑执行过程中轮询状态
解决方案

1. 调整uwsgi配置

按以下内容修改uwsgi.ini,即可满足你“请求进入Flask前丢弃队列超时请求、固定worker数、不主动杀worker”的需求:

[uwsgi]
strict = true
module = flask:app
master = true
processes = 2 # 固定worker数,按需调整为你的目标值即可
threads = 1
enable-threads = true
listen = 128 # 调大监听队列长度,注意要同时修改内核参数net.core.somaxconn为对应值,否则不生效
so-keepalive = true # 开启TCP保活,及时检测客户端断开的连接
listen-queue-timeout = 5 # 核心参数:请求在监听队列中等待超过5秒未被处理直接丢弃,阈值可按需调整
need-app = true
lazy = true
http = 0.0.0.0:5000

如果你可以接受worker被超时重建,也可以打开harakiri = 8配置,自动杀掉处理时间超过8秒的worker,不需要修改业务代码,master进程会自动拉起新的worker,不会影响服务可用性。

2. 修正Flask连接检测逻辑

如果不想用harakiri杀worker,只需要把原有整块的耗时逻辑拆分为小步循环,每次循环检测连接状态即可,修改后的代码如下:

from flask import Flask, request
import requests
import json
import time
import uwsgi

app = Flask(__name__)

@app.route('/')
def test_request():
    # 将4秒耗时拆分为40次100ms的小等待,每次检测连接状态
    for _ in range(40):
        if not uwsgi.is_connected(uwsgi.connection_fd()):
            print("客户端已断开,终止处理")
            return ""
        time.sleep(0.1)
    return "Done"

if __name__ == "__main__":
    app.run(host='0.0.0.0')

3. 压测参数调整

如果要避免压测100%失败,要么把locust的并发用户数调整到2以内,要么按上面的配置调大listen队列长度即可。

备选方案

如果觉得uwsgi配置过于繁琐,也可以改用Gunicorn,对应配置更简洁,通过backlog参数配置监听队列长度、timeout参数配置请求处理超时,也能完全满足你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:06:04