如何在后台按计划运行python脚本?

如何在后台按计划运行python脚本?,python,linux,service,Python,Linux,Service,我有一个小python脚本,它创建了一个从MySQL中提取的数据图。我正试图找到一种方法,定期在后台运行脚本。我尝试了很多方法: 运行脚本的Cron作业 循环计时器 使用&命令在后台运行脚本 这些都有优点和缺点: Cron作业每半小时运行一次以上,似乎会消耗更多的资源 放在脚本中的循环计时器实际上并没有将脚本放在后台,它只是保持脚本运行 Linux&命令是进程的背景,但与真正的Linux服务不同,我无法在不杀死它的情况下重新启动/停止它 有人能给我指出一种方法,让所有这些方法发挥最大的作用吗?为

我有一个小python脚本,它创建了一个从MySQL中提取的数据图。我正试图找到一种方法,定期在后台运行脚本。我尝试了很多方法:

  • 运行脚本的Cron作业
  • 循环计时器
  • 使用&命令在后台运行脚本
  • 这些都有优点和缺点:

  • Cron作业每半小时运行一次以上,似乎会消耗更多的资源
  • 放在脚本中的循环计时器实际上并没有将脚本放在后台,它只是保持脚本运行
  • Linux&命令是进程的背景,但与真正的Linux服务不同,我无法在不杀死它的情况下重新启动/停止它

  • 有人能给我指出一种方法,让所有这些方法发挥最大的作用吗?

    为什么不尝试将脚本制作成一个合适的守护进程呢。这是一个很好的起点

    import os
    import subprocess
    import time
    from daemon import runner
    
    class App():
        def __init__(self):
            self.stdin_path = '/dev/null'
            self.stdout_path = '/dev/tty'
            self.stderr_path = '/dev/tty'
            self.pidfile_path =  '/tmp/your-pid-name.pid'
            self.pidfile_timeout = 5
        def run(self):
    
            try:
                while True:
    
                    ### PUT YOUR SCRIPT HERE ###
    
                    time.sleep(300)
    
            except Exception, e:
                raise
    
    app = App()
    daemon_runner = runner.DaemonRunner(app)
    daemon_runner.do_action()
    

    您可以像任何其他linux服务一样启动/停止/重新启动此脚本。

    一般来说,cron作业可能是一种很好的方法,因为shell方法需要手动干预才能启动它

    有几点建议:

    您可以使用一个锁文件来确保cron作业只启动python脚本的一个实例——在将cron用于更大的作业时,经常会出现问题,因为它在第一个实例实际完成之前启动第二个实例。您只需检查锁文件是否存在,如果不存在,请在脚本开头“触摸”该文件,并在脚本末尾“rm”该文件作为您的最后一个操作即可。如果锁文件存在——只需退出脚本,因为已经有一个实例在运行。(当然,如果脚本死亡,则必须在再次运行脚本之前删除锁定文件)


    此外,如果过度使用资源是一个问题,您可以通过为脚本提供低优先级(前缀为nice-n19)来确保脚本不会占用太多资源

    #1没有任何意义。什么资源?从cron运行并不会神奇地让你的应用程序消耗比平时更多的资源。我需要每分钟运行一次脚本,cron在运行时似乎会出现峰值,而每分钟左右的峰值似乎都会减慢速度。此外,cron在脚本运行后从不离开任务列表,因此每次它运行时都会占用越来越多的内存。这不是侮辱性的,但你可能做错了,或者解释了一些错误的数据——你能发布你正在做和看到的事情的详细信息吗(cron行、ps输出,让你认为它是尖峰等等)?Cron已经存在很长时间了,而且非常稳定,似乎Cron本身不太可能引起问题。顺便说一句,cron应该始终保持运行--这就是它可以在任意时间启动作业的方式。正如您所说,cron作业总体上是好的,但现在op说它必须每分钟运行一次,这意味着作业大部分时间都必须在内存中。所以我会采用守护进程方法。但是,每分钟从MySQL中提取数据听起来并不正确。是的,我同意,如果它必须每分钟都运行,那么守护进程方法值得追求。然而,OP描述的症状(每次运行时都会占用更多内存等)似乎暗示(尽管是间接的)脚本需要相当长的时间才能完成。可能值得对其进行基准测试,找出瓶颈所在,然后找出为所需执行时间/资源提供的实际时间表。我同意@Soz评论,您应该查看查询脚本中可能存在的任何潜在瓶颈。还要对其进行基准测试,看看是否需要超过一分钟的时间才能完成。如果是这样的话,那么cron作业或守护进程循环就不应该是每分钟一次。此外,如果您正在基于MySQL查询在Python中绘制数据,并且该数据持续变化,您可能需要考虑将其保持在一个数组中,这样您的MySQL查询可以简单地用于自数组中最后一个时间戳以来改变的记录。可以将这些新值添加到数组中并绘制数据图表。