You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Crontab重复启动任务实例而非单个实例的问题排查与解决

问题描述

我有一个需要每5分钟运行的Python脚本,通过activate.sh脚本调用:

#!/bin/bash
../../env/bin/python3 ./run.py

对应的crontab定时任务配置如下:

*/5 * * * * cd /var/www/usa/api/BackgroundTasks && /bin/bash ./activate.sh

该配置在3台服务器中的2台运行正常,每次仅启动单个任务实例,但美国服务器会生成多个run.py实例,甚至耗尽服务器内存引发性能问题。以下是核心业务代码app.py:

import time, sys, os, datetime
try:
    sys.path.append("../")

    from Flabstraction.Flabstraction import Pysqlalchemy, MailingService
    from Flabstraction.constants import constants_dict

    from AutomatedReports import schedules_builder_2
    from DeleteOldJobs import delete_old_jobs
    from StallTimers import stop_timers

    constants_selector = "LOCAL"
    path_to_self = os.getcwd()
    selectors = ['/au/','/eu/','/nz/','/usa/','/demo/']
    for sel in selectors:
        if sel in path_to_self:
            constants_selector = sel.upper().replace('/', '')
            break
    constants = constants_dict[constants_selector]

    mail = MailingService()
    sql = Pysqlalchemy('mysql+pymysql', constants["mysql_user"], constants["mysql_pw"], constants["server_ip"], constants["mysql_db"])

    file = open('./background.log', 'w')
    file.write(str(datetime.datetime.now()) + " : running started. \n")

    if constants_selector in ["LOCAL", "US"]:
        schedules_builder_2(sql, constants["timezone"], constants_selector, mail, constants)    
    if constants_selector in ["AU", "NZ", "EU"]:
        delete_old_jobs(sql, constants["timezone"])

    stop_timers(sql, constants["timezone"], constants["_instance_id"])

    file.write(str(datetime.datetime.now()) + " : running stapped. \n")
    file.close()

except Exception as e:
    file = open("./background.log", "w")
    file.write("Error occured: ", e)
    file.close()
    raise e

请问该问题仅出现在一台服务器的原因是什么?如何解决?


可能原因
  1. 任务执行超时:美国服务器对应的constants_selector为US,会执行schedules_builder_2函数,而其他正常服务器执行的是delete_old_jobs。如果US服务器上该任务的数据量更大、逻辑更复杂,导致单次执行时间超过5分钟,下一次cron触发时前一个进程还未结束,就会产生多个实例。
  2. 脚本异常处理错误:代码中异常块的file.write("Error occured: ", e)存在语法错误(write不支持多参数传入),会触发新的TypeError,导致原异常未被正确捕获处理,进程可能异常退出但未清理资源,后续cron仍会启动新进程。
  3. 缺少进程互斥机制:其他服务器任务执行速度快,未暴露问题,但US服务器任务耗时久,脚本和cron配置中没有任何互斥锁机制,无法阻止cron在任务未完成时启动新实例。
  4. 服务器环境差异:美国服务器可能存在系统负载过高、磁盘IO缓慢、数据库响应延迟等情况,导致脚本执行被阻塞,进而超时。

解决办法
  1. 添加进程互斥锁

    • 修改crontab命令,使用flock确保同一时间只有一个实例运行:
      */5 * * * * cd /var/www/usa/api/BackgroundTasks && flock -n ./task.lock /bin/bash ./activate.sh
      
    • 或者在Python脚本中添加进程检查逻辑,比如创建临时PID文件,启动时判断PID文件是否存在且对应进程存活,避免重复启动。
  2. 修复异常处理错误
    将异常块中的错误代码修改为:

    file.write(f"Error occured: {str(e)}\n")
    

    避免因语法错误导致的二次异常,确保异常信息能正确写入日志,便于排查问题。

  3. 优化schedules_builder_2任务性能

    • 分析该函数的执行逻辑,检查是否存在慢查询、循环冗余等问题,针对性优化(比如给数据库添加索引、批量处理数据、异步执行非核心逻辑)。
    • 如果任务确实无法在5分钟内完成,调整cron的执行间隔,或者拆分任务为多个子任务分散执行。
  4. 排查服务器环境问题

    • 查看美国服务器的系统日志、cron日志(通常在/var/log/cron或/var/log/syslog),确认是否有cron重复触发、系统资源不足的情况。
    • 监控脚本执行时的CPU、内存、磁盘IO和数据库响应时间,定位性能瓶颈。

内容的提问来源于stack exchange,提问作者Dimitar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 09:39:26