You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让Flask Blueprint下的各应用分端口运行并解决请求阻塞?

问题根源分析

你猜的完全没错!问题就出在Flask默认的单线程开发服务器上。当你的网站路由(/)发起HTTP请求到同端口的API时,服务器正被当前的网站请求占着,根本腾不出手处理新的API请求,直接陷入了无限等待的死锁状态——这也是为什么POSTMAN能正常调用API(它是外部独立请求,服务器空闲时就能处理),但网站内部调用却卡得一动不动。

解决方案(按推荐优先级排序)

1. 直接调用API函数(最优方案,无HTTP开销)

既然网站和API本来就是同一个Flask应用里的模块,完全没必要绕HTTP请求的弯路,直接调用API的视图函数就行。唯一需要注意的是,Flask的request对象依赖请求上下文,所以我们得手动模拟一下这个环境:

修改你的网站调用代码:

from flask import current_app, request
from your_api_blueprint_file import mod as api_mod  # 替换成你实际的API Blueprint导入路径

mod = Blueprint('site', __name__, template_folder='templates/login')

def load_user(username, password):
    # 模拟请求上下文,构造API需要的authorization对象
    with current_app.test_request_context():
        # 造个和request.authorization结构一致的模拟类
        class MockAuthorization:
            def __init__(self, username, password):
                self.username = username
                self.password = password
        
        request.authorization = MockAuthorization(username, password)
        
        # 直接调用API的login视图函数
        api_response = api_mod.view_functions['login']()
        # 提取返回的JSON数据
        return api_response.get_json()

@mod.route('/')
def index():
    username = 'jeje'
    password = 'jeje'
    data = load_user(username, password)
    return f'<h1>Loaded user data: {data}</h1>'

这种方式既省了HTTP请求的开销,还能完全共享应用内的所有对象和工具,完全不用重复写代码。

2. 启用Flask开发服务器的多线程/多进程模式

如果你非要保留HTTP调用的方式(比如想提前模拟生产环境的调用逻辑),可以在启动Flask应用时开启多线程或多进程,让服务器能同时处理多个请求:

if __name__ == '__main__':
    # 多线程模式,适合IO密集型任务
    app.run(threaded=True)
    # 或者多进程模式,适合CPU密集型场景
    # app.run(processes=2)

不过这种方式会有额外的HTTP开销,而且开发环境下多线程/进程可能会出现上下文缓存、数据库连接之类的小问题,只适合作为过渡方案用。

3. 拆分应用但共享核心代码(适合未来独立部署)

如果以后需要把API和网站拆成独立服务部署,可以提前把共享的核心代码抽离出来,避免重复开发:

  • 创建core目录,放所有共享内容:
    • models.py:USER数据库模型
    • utils.pyvalidehashcreatetoken这类工具函数
    • config.py:SECRET_KEY这类共享配置
  • API应用:导入core模块,创建独立的Flask实例和Blueprint,监听端口5000
  • 网站应用:同样导入core模块,创建独立的Flask实例和Blueprint,监听端口5001

这样拆分后,两个服务完全独立,但核心逻辑只需要维护一份,完美满足你“不重复开发”的需求。

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

火山引擎 最新活动