Flask中如何限制指定endpoint的并发连接数且不影响心跳接口?
解决方案
核心不需要调整心跳路由的注册逻辑,要同时做目标路由精准并发限流 + 请求处理优先级隔离两个配置,仅限流目标路由依然可能出现请求排队堵死心跳的情况:
1. 先调整Gunicorn配置,避免心跳请求排队
- 把Gunicorn的worker类型换成
gevent异步worker,同步worker模式下所有请求会按顺序排队,高负载下心跳请求很容易被前端业务请求堵住 - 配置合理的worker数量:参考公式
CPU核心数*2 +1,不要配置过少,至少预留1个worker的冗余处理心跳请求 - 调低Gunicorn的
backlog参数值,默认是2048,建议调到100以内,超出队列长度的请求直接拒绝,避免队列过长拖垮整个服务
2. 对目标路由做精准的并发限制
不要使用全局限流规则,单独给需要限流的路由加并发控制即可,有两种实现方案可选:
方案1:用flask-limiter库实现
from flask import Flask from flask_limiter import Limiter from flask_limiter.util import get_remote_address app = Flask(__name__) limiter = Limiter( get_remote_address, app=app, storage_uri="memory://", ) # 心跳路由,不添加限流规则 @app.route("/heartbeat") def heartbeat(): return "ok", 200 # 需要限流的目标路由,限制并发数为2 @app.route("/target/endpoint") @limiter.limit("2/second", per_method=True, override_defaults=False) def target_endpoint(): # 你的业务逻辑 return "success"
方案2:用信号量做更精准的并发控制
如果需要严格限制同时处理的连接数而非QPS,可以用信号量实现:
from flask import Flask from threading import Semaphore from functools import wraps app = Flask(__name__) # 初始化信号量,最多允许2个并发请求进入业务逻辑 target_sem = Semaphore(2) def concurrency_limit(sem): def decorator(f): @wraps(f) def decorated_function(*args, **kwargs): with sem: return f(*args, **kwargs) return decorated_function return decorator @app.route("/heartbeat") def heartbeat(): return "ok", 200 @app.route("/target/endpoint") @concurrency_limit(target_sem) def target_endpoint(): # 你的业务逻辑 return "success"
3. 极端资源紧张场景可选优化
如果实例资源实在不足,worker数只能开1个,可以把心跳接口的逻辑放到Gunicorn的post_request钩子中,或者单独开一个轻量级线程处理心跳,完全和业务路由的处理逻辑隔离。
内容的提问来源于stack exchange,提问作者kumalka
相关产品推荐
相关产品推荐

