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

Mod-wsgi重复调用Flask工厂函数的原因及解决办法

问题原因

mod_wsgi在默认的daemon进程模式下(mod_wsgi-express默认启用此模式),Apache主进程会先预加载WSGI模块做语法与有效性检查,随后实际处理请求的daemon进程会再次加载该模块。你的__init__.py在模块级别直接调用了create_app(),这部分代码会在模块加载时执行,因此两次加载就导致工厂函数被调用两次。从日志中同一PID的重复打印也能验证这是同一进程内模块重复加载引发的问题。

解决方案

以下三种方法可以解决该问题,按需选择:

1. 给工厂函数添加单例逻辑(最稳妥,不依赖服务器配置)

修改app.py,通过全局变量确保应用实例只初始化一次,后台线程也只会启动一次:

from flask import Flask
import os

# 全局变量存储已创建的应用实例
_app_instance = None

def create_app():
    global _app_instance
    # 已存在实例则直接返回,避免重复初始化
    if _app_instance is not None:
        return _app_instance
    
    _app_instance = Flask('sample-app')
    
    print("inside factory function!")
    print(f"flask-env {os.environ['FLASK_ENV']}")
    # 在这里启动后台线程,只会执行一次
    
    @_app_instance.route('/', methods=['GET'])
    def hello_world():
        return "Hello! this is a sample flask app!"
    
    return _app_instance

2. 修改WSGI入口,延迟应用创建

调整__init__.py,让mod_wsgi直接调用工厂函数创建应用,而非在模块加载时就初始化:

from src.app import create_app

def application(environ, start_response):
    app = create_app()
    return app(environ, start_response)

这种方式会让应用在第一次请求时才初始化,避免模块预加载阶段的重复调用。

3. 调整mod_wsgi-express启动参数

通过添加参数关闭主进程的预加载检查,避免模块重复加载:
修改Dockerfile中的启动命令,添加--disable-main-process-check参数:

CMD ["mod_wsgi-express", "start-server", "/sample-flask-app/src/__init__.py", "--user", "www-data", "--group", "www-data", "--port", "9090", "--disable-main-process-check"]

这个参数会禁止Apache主进程预加载WSGI模块,仅让daemon进程加载一次,从而避免工厂函数被两次调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:04:50