Flask服务内部嵌套调用requests.get请求本地地址无响应如何解决?
Flask服务内部嵌套HTTP请求卡住的本地修复方案
核心原因
问题根源就是Flask自带的werkzeug开发服务器的请求处理限制:
- 默认单线程处理请求,同一时间只能响应1个请求,嵌套调用自身接口时会出现死锁:外层请求占着线程等待内部请求返回,内部请求拿不到线程无法执行
- 你设置
threaded=True不生效,大概率是同时开启了debug模式的自动重载功能,低版本werkzeug会在重载模式下强制退化为单线程运行,多线程配置不生效
可用本地修复方案
方案1:调整开发服务器启动参数(业务代码零改动)
启动服务时关闭自动重载,同时开启多线程即可,两种启动方式对应配置:
- 命令行启动:
flask run --threaded --no-reload - 代码内启动:
app.run(threaded=True, use_reloader=False)
该方案完全不需要修改业务代码,staging环境用的是支持多进程/多线程的WSGI服务器(如Gunicorn、uWSGI),本身就不会出现这个问题,两套环境不需要做差异化处理。
方案2:环境自适应请求逻辑(兼容本地+staging环境)
封装统一的内部请求工具函数,根据环境自动切换请求方式,避免两套环境分开改代码:
import os import requests def internal_get(path): # 本地开发环境用test_client发请求,不需要走网络 if os.getenv("FLASK_ENV") == "development": from flask import current_app with current_app.test_request_context(): with current_app.test_client() as client: return client.get(path) # 非开发环境用requests走正常HTTP请求 else: full_url = f"http://localhost:5000{path}" return requests.get(full_url)
业务代码中把所有嵌套调用requests.get的地方替换为调用internal_get即可,两边环境都可以正常运行。
方案3:本地换用多进程WSGI服务器
本地开发直接用和staging环境同类型的多进程WSGI服务器,避免开发服务器的特性差异,比如用Gunicorn:
- 安装Gunicorn:
pip install gunicorn - 启动服务:
gunicorn -w 2 你的启动文件名称:app(-w参数指定工作进程数,设为2即可支持嵌套请求)
优化建议
不推荐在业务逻辑中用HTTP请求调用自身服务的接口,建议直接抽离接口的公共逻辑为独立函数,需要复用的地方直接调用函数即可,性能更高,也不会出现并发死锁问题。
内容的提问来源于stack exchange,提问作者thekthuser
相关产品推荐
相关产品推荐

