如何在Python的Flask应用启动时同时启动其他Python代码

用 flask 写了几个 restful 接口, 同时我又有一段 rabbitmq 的消息消费代码, 我想把 rabbitmq 的消息消费代码放到 flask 中, 随 flask 启动应该怎么搞?

if __name__ == '__main__':
    app.run()
    msg_comsue)

上面这种方式不行, 因为我是用 tornado 来调 app 的.

from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from run import app

http_server = HTTPServer(WSGIContainer(app)) http_server.listen(5000) IOLoop.instance().start()


如何在Python的Flask应用启动时同时启动其他Python代码

4 回复

写个启动函数,在 if name == “main”: 里面调用


在Flask应用启动时运行其他代码,最直接的方法是使用Flask的@app.before_first_request装饰器,但它在Flask 2.3+已被弃用。现在更推荐使用@app.before_request配合状态检查,或者更好的——使用应用工厂模式配合app.app_context()

这里给你两个最实用的方案:

方案一:使用app.before_request(简单直接)

from flask import Flask, g
import threading

app = Flask(__name__)
_background_started = False

def start_background_tasks():
    """你的启动代码放在这里"""
    print("启动后台任务...")
    # 例如:启动一个监控线程
    def monitor():
        while True:
            # 你的监控逻辑
            pass
    thread = threading.Thread(target=monitor, daemon=True)
    thread.start()

@app.before_request
def before_first_request():
    global _background_started
    if not _background_started:
        start_background_tasks()
        _background_started = True

@app.route('/')
def hello():
    return "Flask应用已启动,后台任务正在运行"

if __name__ == '__main__':
    app.run()

方案二:使用应用工厂模式(生产环境推荐)

from flask import Flask
import threading

def create_app():
    app = Flask(__name__)
    
    # 注册路由等
    @app.route('/')
    def hello():
        return "应用运行中"
    
    # 应用上下文启动后台任务
    with app.app_context():
        start_background_tasks()
    
    return app

def start_background_tasks():
    print("启动初始化任务...")
    # 初始化数据库连接、加载配置等
    thread = threading.Thread(target=background_worker, daemon=True)
    thread.start()

def background_worker():
    while True:
        # 你的后台逻辑
        pass

if __name__ == '__main__':
    app = create_app()
    app.run()

关键点:

  • 如果只是想在第一个请求前执行,用方案一
  • 如果要在应用启动立即执行(即使没收到请求),用方案二
  • 记得把后台线程设为daemon=True,这样主进程退出时线程会自动结束

用应用工厂模式更干净。

你这样混着当然不行

tornardo 假设你的代码就是个干净的无状态的 web app,取决于你的设置,可能多线程或多进程跑。
嵌的 msg_consume 要防止竞态就需要跨进程通讯,这会很恶心
建议分离出来,我猜 msg_comsue 就是隔段时间检查是吧,做个 /msg_comsue 请求触发相应函数,做好安全限制本地访问,然后 cron 访问就好

如果需要性能 /更复杂,用队列,比如 celery。另外启动后端处理

多线程 /多进程异步掉~ 如果需求更复杂,上 Celery 等工具吧

回到顶部