我正在使用 Flask 来开发网站,在开发过程中我使用以下文件运行 Flask:
#!/usr/bin/env python
from datetime import datetime
from app import app
import config
if __name__ == '__main__':
print('################### Restarting @', datetime.utcnow(), '###################')
app.run(port=4004, debug=config.DEBUG, host='0.0.0.0')
当我启动服务器时,或者当它因文件已更新而自动重新启动时,它总是显示打印行两次:
################### Restarting @ 2014-08-26 10:51:49.167062 ###################
################### Restarting @ 2014-08-26 10:51:49.607096 ###################
虽然这并不是真正的问题(其余部分按预期工作),但我只是想知道为什么它会这样?有什么想法吗?
Werkzeug 重新加载器会生成一个子进程,以便每次代码更改时它都可以重新启动该进程。 Werkzeug 是当您调用
app.run()
时为 Flask 提供开发服务器的库。
restart_with_reloader()
功能代码;您的脚本将再次运行 subprocess.call()
。如果您将 use_reloader
设置为
False
,您会看到该行为消失,但您也会失去重新加载功能:app.run(port=4004, debug=config.DEBUG, host='0.0.0.0', use_reloader=False)
您也可以在使用
flask run
命令时禁用重新加载器:
FLASK_DEBUG=1 flask run --no-reload
如果您想检测何时处于重新加载子进程中,可以使用
werkzeug.serving.is_running_from_reloader
函数
:
from werkzeug.serving import is_running_from_reloader
if is_running_from_reloader():
print(f"################### Restarting @ {datetime.utcnow()} ###################")
但是,如果您需要设置模块全局变量,那么您应该在函数上使用
@app.before_first_request
装饰器
并让该函数设置此类全局变量。当第一个请求到来时,每次重新加载后它都会被调用一次:
@app.before_first_request
def before_first_request():
print(f"########### Restarted, first request @ {datetime.utcnow()} ############")
请务必考虑到,如果您在使用分叉或新子流程来处理请求的全面 WSGI 服务器中运行此程序,则每个新子流程都会调用
before_first_request
处理程序
可能。
flask run
命令,则不会使用
app.run
的任何选项。要完全禁用重新加载器,请传递 --no-reload
:FLASK_DEBUG=1 flask run --no-reload
此外,
__name__ == '__main__'
永远不会为真,因为应用程序不是直接执行的。使用
Martijn 的答案中的相同想法,除了没有
__main__
块。if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
# do something only once, before the reloader
if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
# do something each reload
app.debug
设置为
False
来解决它。将其设置为 True
会导致我的 __name__ == "__main__"
被调用两次。这将避免我的烧瓶运行两次。
if __name__ == '__main__':
app.run(debug=True, use_reloader=False)
WEB_CONCURRENCY
设置的配置。要设置为一个,您可以在控制台中编写
heroku config:set WEB_CONCURRENCY=1
import os.path
from apscheduler.schedulers.background import BackgroundScheduler
def set_lastrun():
f = open('/tmp/lastrun','w')
f.write(f'{datetime.now()}')
f.close()
def get_lastrun():
return os.path.isfile('/tmp/lastrun')
def start_job_scheduler():
scheduler = BackgroundScheduler()
scheduler.add_job(func=your_job, trigger="interval", seconds=300)
scheduler.start()
app = Flask(__name__)
def app_init():
if not get_lastrun():
set_lastrun()
start_job_scheduler()
`