Flask多个应用不能直接多次调用app.run():因Werkzeug内置WSGI服务器仅接受一个可调用对象,重复调用会报Address already in use或静默覆盖;必须通过DispatcherMiddleware统一入口按路径前缀分发,各子应用需独立配置APPLICATION_ROOT、静态资源路径等。

Flask多个应用不能直接 run() 多次
Flask 的 app.run() 启动的是单个 WSGI 应用,调用多次会报错 Address already in use 或直接覆盖前一个实例。这不是端口冲突那么简单——根本上是 WSGI 服务器(如 Werkzeug 内置服务器)只接受一个可调用的 application 对象。想让多个 Flask 应用共存,必须把它们“塞进”同一个 WSGI 入口。
DispatcherMiddleware 是 Werkzeug 提供的标准合并方案
它不是 Flask 自带的,但和 Flask 深度兼容,作用就是把多个 WSGI 应用按 URL 前缀路由分发。关键点在于:每个子应用必须是独立的 WSGI 可调用对象(即 Flask 的 app 实例),且挂载路径以 / 开头、结尾不带变量。
-
DispatcherMiddleware第一个参数是“主应用”(可为None),后续元组列表格式为(mount_path, wsgi_app) - 挂载路径必须唯一,且不会自动去除重复斜杠,
/api和/api/被视为不同路径 - 子应用内部的
url_for()仍生成相对路径,不会自动补前缀;需设app.config['PREFERRED_URL_SCHEME'] = 'http'并在反向代理时配好X-Forwarded-Prefix - 示例:
from werkzeug.middleware.dispatcher import DispatcherMiddleware from werkzeug.serving import make_server <p>app1 = Flask('blog') app2 = Flask('admin')</p><h1>注意 mount_path 必须是字符串,且以 / 开头</h1><p>application = DispatcherMiddleware(None, { '/blog': app1, '/admin': app2 })</p><h1>启动时只 run 这一个 application</h1><p>server = make_server('localhost', 5000, application) server.serve_forever()
挂载后静态文件 404 是最常见坑
Flask 子应用默认静态路径(static_folder)仍指向自身目录,但请求路径已被前置了 mount_path,比如 /blog/static/style.css 会进 app1,而 app1 的静态视图只认 /static/...。结果就是 404。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 解决方法一:子应用启用
send_file手动处理,或改写static_url_path为/blog/static,再配好static_folder路径 - 解决方法二:统一由主 WSGI 层处理静态资源,比如用
SharedDataMiddleware或 Nginx 直接服务 - 更现实的做法:开发期用
flask run --reload不适用DispatcherMiddleware,上线才切到 WSGI 模式并配静态托管
别指望 Blueprint 替代 DispatcherMiddleware
Blueprint 是组织代码的逻辑单元,不是部署单元。多个 Blueprint 注册到同一个 Flask app 上,共享路由表、配置和生命周期,无法隔离请求上下文、中间件或错误处理器。而 DispatcherMiddleware 下每个子应用有完全独立的 app.config、before_request、日志配置,甚至可以是不同版本的 Flask。
立即学习“Python免费学习笔记(深入)”;
- 如果你需要两个应用用不同数据库连接、不同 SECRET_KEY、不同 JWT 密钥,就必须用
DispatcherMiddleware或反向代理 - 如果只是模块拆分,用 Blueprint + 工厂函数更轻量
- 注意:子应用中定义的 CLI 命令(
@app.cli.command)不会自动注册到主进程,得单独调用或封装
实际部署时,DispatcherMiddleware 适合轻量合并,但一旦子应用规模上升、需要独立健康检查、不同并发模型或异步支持,就该切到反向代理(Nginx / Traefik)——那才是生产环境的标准解法。

















