Python Apache终止Flask进程时如何调用函数?
我有一个Flask应用程序运行在Apache HTTPD后面。Apache被配置为具有多个子进程 Flask应用程序在服务器上创建一个文件,文件名等于其进程ID。 代码如下所示:Python Apache终止Flask进程时如何调用函数?,python,apache,flask,termination,Python,Apache,Flask,Termination,我有一个Flask应用程序运行在Apache HTTPD后面。Apache被配置为具有多个子进程 Flask应用程序在服务器上创建一个文件,文件名等于其进程ID。 代码如下所示: import os @app.before_first_request def before_first_request(): filename = os.getpid() with open(filename, 'w') as file: file.write('Hello') 当
import os
@app.before_first_request
def before_first_request():
filename = os.getpid()
with open(filename, 'w') as file:
file.write('Hello')
当子进程被终止/结束/终止时,我希望Flask应用程序删除此文件
删除文件并不十分重要,因为这些文件不会占用太多空间,所以如果发生奇怪的错误,我不需要处理它们。但是对于正常的工作流,我希望在Apache关闭Flask进程时进行一些清理
有什么好办法吗?最简单的办法是在Apache进程之外处理这个问题。无法保证进程总是删除文件(例如,如果重新启动apache服务器mid请求) 我过去采用的方法是使用
cron
。在存储库中的某个地方编写一个小脚本,并按计划执行(通常每天都可以)。此脚本可以清除directorty中所有超过24小时的文件,因此您将始终拥有1天的文件滚动窗口
这有两个好处:
大多数脚本语言都有一个小的包装类,可用于使
cron
更友好。Ruby最流行的一种方法是。在服务器控制的Python进程(例如在Apache WSGI上下文中运行的Flask应用程序,或者更好的是在Apache后面的Gunicorn中运行的Flask应用程序)优雅终止之前,添加清理功能的最佳方法是使用退出处理程序
在您的原始示例的基础上,添加了执行.pid
文件清理的退出处理程序:
import atexit
import os
filename = '{}.pid'.format(os.getpid())
@app.before_first_request
def before_first_request():
with open(filename, 'w') as file:
file.write('Hello')
def cleanup():
try:
os.remove(filename)
except Exception:
pass
atexit.register(cleanup)
Apache/mod_wsgi当然总是试图确保调用atexit回调,即使在由于请求超时等情况而必须关闭流程的情况下,在gunicorn中也没有很好的保证,在gunicorn下使用atexit时,您必须比在各种情况下使用atexit时更加小心。在这两种情况下,您都不应该依赖它,并且应用程序应该能够适应后续运行中存在的文件(如果该文件不应该存在的话)。正如其他答案所描述的,可能需要一个单独的任务来删除。对于其他一些WSGI服务器,甚至可能根本不会调用atexit回调。我认为uWSGI的情况仍然如此,除非您强制它使用单个解释器,因为它不会采取措施确保在子解释器中调用atexit回调。它必须采取特殊的步骤,因为Python不会在子解释器中调用atexit回调,Apache/mod_wsgi正在使用特殊的技巧来确保它们是正确的。great info@GrahamDumpleton!感谢您的支持,以及异常保护,绕过
os.remove
call。