Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Apache终止Flask进程时如何调用函数?_Python_Apache_Flask_Termination - Fatal编程技术网

Python Apache终止Flask进程时如何调用函数?

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') 当

我有一个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')
当子进程被终止/结束/终止时,我希望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。