【问题标题】:how to restart a python program after it crashespython程序崩溃后如何重新启动
【发布时间】:2021-09-05 18:51:45
【问题描述】:

我有一个 python 脚本,它启动一个程序并通过它自动执行,不断处理新数据并保存到预设目录。
永久运行 Python 脚本、在发生错误时记录错误并在崩溃时重新启动的推荐方法是什么?
到目前为止,我遇到了 os.execv 并开始这样做:

import sys
import os
 
def pyexcept(t, v, tb):
   import traceback
## restarts the script
os.execv( sys.executable, '')

但我经常在试图弄清楚下一步时遇到困难,谁能解释一下我可以采取的下一步措施,ty!

【问题讨论】:

  • 您可以只处理异常并使用logging 库来记录事件
  • 不要永远运行脚本 - 使用 cron 按计划运行它。

标签: python python-3.x


【解决方案1】:

当python脚本崩溃时,程序不再运行,因此脚本无法执行更多行代码。

你有两个选择:

  1. 确保您的 python 脚本不会崩溃,这是非常推荐的。您可以通过处理程序抛出的异常来做到这一点。

选项 1

我假设你是 python 新手,所以这里有一个处理异常的 python 脚本示例再次调用相同的函数。

from time import sleep

def run_forever():
    try:
        # Create infinite loop to simulate whatever is running
        # in your program
        while True:
            print("Hello!")
            sleep(10)

            # Simulate an exception which would crash your program
            # if you don't handle it!
            raise Exception("Error simulated!")
    except Exception:
        print("Something crashed your program. Let's restart it")
        run_forever() # Careful.. recursive behavior
        # Recommended to do this instead
        handle_exception()

def handle_exception():
    # code here
    pass

run_forever()
  1. 如果你想重新启动 python 脚本,你需要另一个 python 脚本(假设你想用 python 来做这个)来检查进程是否还活着,如果没有,然后再次运行它蟒蛇。

选项 2

这是通过命令python test.py 启动另一个名为'test.py' 的python 脚本的脚本。 确保你有正确的文件路径,如果你把脚本放在同一个文件夹中,你通常不需要完整路径,只需要脚本名称。

值得注意的是,确保您的系统能够识别命令“python”,在某些情况下它可以被'python3'

script_starter.py

from subprocess import run
from time import sleep

# Path and name to the script you are trying to start
file_path = "test.py" 

restart_timer = 2
def start_script():
    try:
        # Make sure 'python' command is available
        run("python "+file_path, check=True) 
    except:
        # Script crashed, lets restart it!
        handle_crash()

def handle_crash():
    sleep(restart_timer)  # Restarts the script after 2 seconds
    start_script()

start_script()

如果你对我用于测试文件的代码感兴趣:'test.py',我把它贴在这里。

test.py

from time import sleep
while True:
    sleep(1)
    print("Hello")
    raise Exception("Hello")

【讨论】:

  • 另一种选择是使用 Kubernetes 并在容器中运行脚本,但这可能有点矫枉过正 ;-)
  • 感谢您的帮助,我已经使用了第一种方法,我想获得第二个选项的示例,我正在使用 Windows 10。
  • @Shone118 好的,我将在今天晚些时候准备好解决方案 :)
【解决方案2】:

不言而喻,如果 Python 脚本崩溃了,它就无法自行重启,因为它不再驻留在内存中。因此,答案必须来自 Python 之外的某些东西,它在比应用程序更低的抽象级别上运行。

Linux 通常使用 systemd 解决这个问题。您可以创建一个描述应用程序运行的单元文件并启动该服务。 systemd 将监控正在运行的进程,如果它死了,则重新启动它。

Windows 通常使用 Windows 服务来解决这个问题,这些服务是带有特殊 win32 API 包装器的可执行文件,允许系统调用它们以检查它们的状态、停止它们或重新启动它们。 NSSM(非吸吮服务管理器)是一个有用的实用程序,可以从任意命令创建服务。

【讨论】:

    【解决方案3】:

    您必须使用一些外部服务来监视您的 python 应用程序。在 Windows 中,您可以使用 Windows Service Wrapper 将 Python 应用程序作为 Windows 服务运行。

    Windows 服务包装器 (WinSW) 最初是为在 Windows 机器中作为 Windows 服务运行 Jenkins 客户端和服务器而开发的。但与其他服务包装器不同的是,WinSW 允许您运行任何其他应用程序,例如 python。

    您可以将所有配置详细信息作为 XML 文件提供。

    您可能感兴趣的一些配置

    • executable --> 您可以定义要运行的可执行文件(在您的情况下为python
    • aruments --> 你可以为可执行文件提供参数(例如——你可以提供你的应用程序)
    • onFailure --> 您可以使用onfailure 配置来指定应用程序失败时的处理方式。
    • logpath --> 您可以指定日志的位置。

    还有更多。请阅读this文件以了解所有配置。

    您应该将配置 XML 文件放在 WinSW 可执行文件所在的同一目录中。还有一些必须实现的配置需要管理 Windows 服务(idnamedescriptionexecutable)。

    您可以从此link下载最新版本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-09
      • 1970-01-01
      相关资源
      最近更新 更多