运行 自定义日期时间的基于命令的程序 (Add/modify/delete)

Run a command based program at a custom date-time (Add/modify/delete)

我有一个 python 脚本,它接受一些参数作为参数,我需要 运行 基于此脚本在给定日期和时间与其他参数一起执行任务。我正在使用所有给定的参数执行 UI 到 add/modify/delete 此类任务。我该怎么做?有没有可用的工具?我不认为 crontabs 是最好的解决方案,尤其是由于经常需要任务 modification/deletion。要求是 linux 机器。

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

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

一个解决方案是在后台设置一个守护进程 运行ning,定期唤醒以执行应有的任务。

它会休眠 x 分钟,然后在数据库中查询所有待办日期时间小于当前日期时间的未完成任务。它会执行任务,将任务标记为已完成,保存结果并返回休眠状态。

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

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

  1. 使用 python scheduler 以编程方式安排您的 没有 cron 的任务。这个调度程序脚本可以 运行 作为守护进程或通过 cron 作业一直 运行。
  2. 使用pythoncrontab module修改 来自 python 程序本身的 cron 作业

如果脚本的参数是在不同的时间安排(或用户提供的)动态生成的,那么唯一的方法就是使用 GUI 获取更新的参数和 运行 python 脚本来修改计划任务。

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 点执行一个函数。

你可以用 timer unitssystemd 来完成。比 cron 有什么优势?

  1. 可以定义对其他服务的依赖性,以便其他服务 必须首先执行服务,以便启动服务 (需要),或者服务不会启动,如果它会进入 当前与另一个服务冲突 运行(冲突)。
  2. 相对时间是可能的:您可以使计时器单元启动一个 执行后每十分钟服务一次。这个 消除了在某些时候导致的重叠服务调用 CPU 因为 cron 中的间隔太低而被阻止。
  3. 由于Timer Units本身也是服务,所以可以 优雅地激活或停用,而 cronjobs 只能是 通过注释掉或删除它们来停用。
  4. 与 定时任务

举个例子:

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

[Unit]
Description=Description of your app.

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

Timer Unit 指定上面定义的服务单元在启动后 30 分钟启动,然后在最后一次 activity 后 10 分钟启动。

文件:/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

我自己找到了答案,即 Timers 因为我的经验和用例是在 java 中,所以我通过在中创建 REST API 来使用它spring 并管理 java 层中计时器的内存缓存作为数据库的副本。可以使用任何语言的定时器来实现类似的功能。现在我可以 运行 任何基于控制台的应用程序并在各自的计时器中传递所有必需的参数。类似地,我可以通过简单地从 hashmap 调用相应计时器上的 .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;
    }

谢谢大家的建议。