python - 如果服务器被CTRL + C杀死或中断或崩溃,请采取措施

标签 python flask error-handling bottle atexit

我有一个不断运行的应用程序(从Linux开始使用screen -S myapp python3 app.py,然后将其分离)。它可能是Bottle应用程序,Flask应用程序或任何其他涉及永久运行的事件循环的系统:

import anyframework   # can be bottle, flask or anything else
import sqlite3

@route('/')
def index():
    c = db.cursor()
    c.execute('INSERT INTO test VALUES (?)', ('test',))
    c.close()  # we can't commit here for *each* client request, it would eat 100ms for each request
    return 'hello'

@route('/makeitcrash')
def index():
    sdlfksdfs  # this will generate an error

def cleanup():
    db.commit()

db = sqlite3.connect('test.db')
run()

如何在服务器终止的所有可能情况下可靠地确保cleanup()(以及数据库提交)被调用? ,即:
  • (如果服务器已被SIGKILL,SIGTERM杀死)
  • (如果服务器代码有错误)(例如,如果访问了http://example.com/makeitcrash)则为
  • (如果我在终端中(运行的screen内)执行CTRL + C)



  • 我本打算使用atexit并在各处添加try: except:,但我认为它将引入许多代码重复,以便为每条路线插入try: except:

    这个问题的一般解决方案是什么?

    最佳答案

    一种方法是捕获信号并在收到信号时进行清理。

    import signal
    import sys
    
    from bottle import run
    
    def handle_signal(signum, frame):
        print(f'handling signal {signum}')
        # do cleanup
        sys.exit(0)
    
    signal.signal(signal.SIGINT, handle_signal)
    # also SIGTERM, et al.
    
    run()
    

    注意事项

    正如@MarkAllen指出的,SIGKILL永远不会被捕获。

    我也建议不要一开始就这样处理问题。相反,请查看是否可以设计Web应用程序,以便在关机时无需进行任何清理。 (例如,对每个请求执行持久写入,而不是在内存中进行缓冲。)减少所保持的状态量将有助于简化许多事情,包括如何处理崩溃/关机。

    关于python - 如果服务器被CTRL + C杀死或中断或崩溃,请采取措施,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61609523/

    相关文章:

    python - 在 AND 和 OR 处拆分字符串,保留分隔符

    python - 如何选择不同级别的多个列?

    python - Tensorflow - 有条件地为张量赋值

    python-3.x - 在 Mac (OS High Sierra) 上安装 Flask-mysqldb (python 3) 时出错

    php - Apache 服务器日志错误。 AH00126 : Invalid URI in request GET, 等

    Python pandas 自动对列进行排序

    docker - 无法与具有多个Flask容器实例的Nginx docker反向代理

    javascript - <script> 在 Flask html 页面中的放置

    error-handling - Elixir/Phoenix 处理 erlang 错误

    asp.net - 覆盖asp.net/IIS错误页面