在自定义日期时间运行基于命令的程序(添加/修改/删除)

时间:2018-07-16 16:19:45

标签: java python scheduled-tasks job-scheduling

我有一个使用少量参数作为参数的python脚本,我需要在给定的日期和时间与其他参数一起运行基于此脚本的任务。我正在制作一个UI,以使用所有给定的参数添加/修改/删除此类任务。我该怎么做?有没有可用的工具?我不认为crontabs是解决此问题的最佳方法,特别是由于经常需要修改/删除任务。要求是针对Linux机器的。

一个解决方案可能是: 创建一个API以读取存储在数据库中的所有任务以及时执行python脚本,并每隔几分钟通过crontab调用该API。

但是我正在寻找更好的解决方案。欢迎提出建议。

5 个答案:

答案 0 :(得分:3)

我假设所有参数(命令行)都是预先知道的,在这种情况下,您有几个选择

  1. 使用python scheduler以编程方式安排您的时间 没有cron的任务。该调度程序脚本可以作为守护程序运行,也可以通过cron作业始终运行。
  2. 使用python crontab module进行修改     来自python程序本身的cron作业

如果脚本的参数是在各种时间表(或用户提供的)上动态生成的,那么唯一的办法就是使用GUI获取更新的参数并运行python脚本来修改cron作业。

答案 1 :(得分:3)

from datetime import datetime
from threading import Timer

x=datetime.today()
y=x.replace(day=x.day+1, hour=1, minute=0, second=0, microsecond=0)
delta_t=y-x

secs=delta_t.seconds+1

def hello_world():
   print "hello world"
   #...

t = Timer(secs, hello_world)
t.start()

这将在第二天凌晨1点执行一个功能。

答案 2 :(得分:2)

您可以将timer unitssystemd一起使用。与cron相比有什么优势?

  1. 可以定义对其他服务的依赖关系,以便彼此 必须先执行服务,以便完全启动服务 (需要),否则服务将无法启动 与当前正在运行的另一个服务发生冲突(冲突)。
  2. 可能存在相对时间:您可以使定时器单元启动一个 执行后每十分钟进行一次服务。这个 消除了在某些时候导致 由于cron中的间隔太短,CPU被阻塞。
  3. 由于计时器单元本身也是服务,因此它们可以 优雅地激活或停用,而cronjobs只能是 通过注释掉它们或删除它们来取消激活。
  4. 相对于时间和空间的易于理解的指示 Cron。

以下是一个示例:

文件:/etc/systemd/system/testfile.service

[Unit]
Description=Description of your app.

[Service]
User=yourusername
ExecStart=/path/to/yourscript

计时器单元指定要在启动后30分钟启动,然后在上一次活动后十分钟启动上面定义的服务单元。

文件:/etc/systemd/system/testfile.timer

[Unit]
Description=Some description of your task.

[Timer]
OnBootSec=30min
OnUnitInactiveSec=10min
Persistent=true
User=testuser
Unit=testfile.service

[Install]
WantedBy=timers.target

答案 3 :(得分:1)

一种解决方案是在后台运行守护程序,并定期唤醒以执行应有的任务。

它将休眠x分钟,然后在数据库中查询所有尚未完成的任务,这些任务的datetime小于当前datetime。它将执行任务,将任务标记为已完成,保存结果并返回睡眠状态。

您还可以使用无服务器计算,例如AWS Lambda,可以为triggered by scheduled events。它似乎支持crontab表示法或类似的表示法,但您也可以在每次运行一次时添加下一个事件。

答案 4 :(得分:-3)

我自己找到了答案,即 Timers ,因为我的经验和用例是在Java中,所以我通过在Spring中创建REST API并在Java层中以以下方式管理计时器的内存缓存来使用它:数据库的副本。可以使用任何语言的计时器来实现类似的功能。现在,我可以运行任何基于控制台的应用程序,并在各自的计时器内传递所有必需的参数。同样,我可以通过简单地从哈希图中调用相应计时器上的 .cancel() 方法来更新或删除任何计时器。

  public static ConcurrentHashMap<String, Timer> PostCache = new ConcurrentHashMap<>();
  public String Schedulepost(Igpost igpost) throws ParseException {
        String res = "";
        TimerTask task = new TimerTask() {
            public void run() {
                System.out.println("Sample Timer basedTask performed on: " + new Date() + "\nThread's name: " + Thread.currentThread().getName());
                System.out.println(igpost.getPostdate()+" "+igpost.getPosttime());
            }
        };
        DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date date = dateFormatter.parse(igpost.getPostdate()+" "+igpost.getPosttime());
        Timer timer = new Timer(igpost.getImageurl());
        CacheHelper.PostCache.put(igpost.getImageurl(),timer);
        timer.schedule(task, date);
        return  res;
    }

谢谢大家的建议。