如何在同一Python脚本中关闭Flask服务器并更换IP重启?
Flask服务器同脚本内切换IP重启实现方案
核心问题说明
Flask默认开发服务器没有直接对外暴露关闭接口,需要借助Werkzeug的服务器实例实现关闭操作,同时要处理线程作用域问题,避免变量引用错误。
实现步骤与代码修改
1. 保存Werkzeug服务器实例
替换默认的app.run()为werkzeug.serving.run_simple启动服务,这样能直接拿到服务器实例,方便后续执行关闭操作。
2. 实现安全关闭逻辑
通过服务器实例的shutdown()方法终止当前服务,同时等待旧线程完全退出后再启动新服务。
3. 修复线程变量作用域问题
将服务器实例、线程对象声明为全局变量,避免函数内局部变量覆盖导致的错误。
完整修改后代码
import threading from flask import Flask, request from werkzeug.serving import run_simple app = Flask(__name__) server = None # 存储Werkzeug服务器实例 flask_thread = None @app.route('/') def hello(): return 'Hello, World!' @app.route('/restart', methods=['GET']) def restart(): global flask_thread, server, new_IP # 关闭当前运行的服务器 if server: server.shutdown() # 等待旧线程完全退出 if flask_thread and flask_thread.is_alive(): flask_thread.join() # 启动新IP的Flask服务 flask_thread = threading.Thread(target=start_flask, args=(new_IP,)) flask_thread.start() return 'Restarted with new IP!' def start_flask(ip): global server # 用run_simple启动,获取服务器实例 server = run_simple(ip, 5000, app, threaded=True) old_IP = '123.123.123.123' new_IP = '234.234.234.234' # 启动初始服务 flask_thread = threading.Thread(target=start_flask, args=(old_IP,)) flask_thread.start()
关键细节解释
- 服务器实例控制:
run_simple会返回WSGIServer对象,调用其shutdown()方法可直接终止服务,这是实现重启的核心。 - 全局变量处理:通过
global关键字声明变量,确保函数内外操作的是同一个服务器和线程对象,避免局部变量冲突。 - 线程等待机制:
flask_thread.join()确保旧服务完全停止后再启动新服务,防止端口占用或资源竞争。 - 多线程模式:
run_simple的threaded=True参数开启多线程,保证重启请求能被正常处理(单线程模式下重启请求会被阻塞)。
注意事项
- 该方案仅适用于Flask开发服务器,生产环境建议使用Gunicorn、uWSGI等专业服务器,这类服务有成熟的重启机制。
- 确保新旧IP均能被当前机器绑定,否则新服务启动会失败。
- 如需修改端口,调整
run_simple的第二个参数即可。
内容的提问来源于stack exchange,提问作者cssstudent
相关产品推荐
相关产品推荐

