V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
monkeyNik
V2EX  ›  程序员

meschedule: 基于时间和依赖关系的简易任务调度器

  •  
  •   monkeyNik ·
    Water-Melon · 2021-08-27 18:16:38 +08:00 · 408 次点击
    这是一个创建于 988 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现今开源的任务调度器比较有名的如 airflow,它其实是一个功能很丰富的工具集了,功能强大加可视化。但有时我只想使用一个简单的任务调度器,可以很快上手使用,不求对上万任务的掌控和跨界点调度,那么就是今天笔者推荐的调度器mescedule

    安装

    meschedule 是使用 melang 语言进行编写的,所以只需要安装好 melang 解释器即可运行。melang 支持 UNIX 及 windows 环境,但由于 windows 提供的系统 API 的差异问题,在 windows 上无法使用 meschedule 。

    关于 melang 的安装可参考:传送门

    启动

    启动也是非常简单的,执行如下命令即可:

    $ melang scheduler.mln
    

    调度器配置

    meschedule 启动时会加载 config.json 中的配置,所以我们先简单介绍一下这个配置:

    {
        "path": "test", //任务所在目录的路径
        "concurrency": 10, //启用多少个协程处理任务
        "delta_sec": 15, //cron 格式的时间调度器都是在分钟级的,但具体到秒级则可使用这个配置项,当前配置表示在指定分钟的第 15 秒开始执行任务
        "data": {} //这里给出一些自定义变量,这些变量会被用于替换每个任务配置中要执行的 shell 命令字符串中的变量
    }
    

    这里需要注意,path 指定的路径可以是一个包含子目录的目录。调度器只会获取其中名字不以.开头但以.json结尾的 json 文件的内容作为每个任务的任务配置。

    任务配置

    每个任务都是一个简单的 json 文件,格式如下:

    {
        "name": "task name", //任务名
        "period": "* * * * *", //cron 格式的时间配置,但暂时不支持 - 指示的范围符号
        "deps": [],//依赖的任务数组,每个数组元素是一个字符串,其值应与被依赖任务的 json 中的 name 字段值保持一致
        "cmd": "shell command",//具体的 shell 命令
        "data": {}//用于替换 shell 命令中的自定义变量
    }
    

    这里需要额外说明一下,调度器配置中的 data 相当于一个全局范围的变量配置,而任务配置中的 data 相当于该任务范围的变量配置,因此任务配置的 data 将具有更高的优先级。

    除此以外,任务配置支持一个默认的变量名PWD,这个变量的值是当前任务 json 文件所在目录路径。

    举例:

    {
        "name": "a", //任务名 a
        "period": "* * * * *", //每分钟执行一次
        "deps": ["b", "c"], //该任务依赖于任务 b 和 c,即如果 a 执行时间到来时,任务 b 和 c 也要执行或正在执行,那么 a 必须等到这两个任务执行完成才可以被执行
        "cmd": "echo CMD", //CMD 是一个自定义变量,被定义在 data 中,故这个命令就是 echo a
        "data": {
            "CMD": "a"
        }
    }
    

    举例

    有一个名为 test 的目录用于存放所有任务配置,结构如下:

    test
       |- a.json
       |- foo
            |- b.json
            |- d
            |- bar
                |- c.json
    

    a.json

    {
        "name": "a",
        "period": "* * * * *",
        "deps": [],
        "cmd": "echo PWD",
        "data": {
        }
    }
    

    b.json

    {
        "name": "b",
        "period": "* * * * *",
        "deps": ["a"],
        "cmd": "echo PWD",
        "data": {
        }
    }
    

    c.json

    {
        "name": "c",
        "period": "* * * * *",
        "deps": ["b"],
        "cmd": "echo PWD",
        "data": {
        }
    }
    

    调度器配置如下:

    {
        "path": "test",
        "concurrency": 10,
        "delta_sec": 15,
        "data": {}
    }
    

    那么当我们执行了调度器后,每分钟输出的结果就是:

    example
    
    example/foo
    
    example/foo/bar
    
    ...
    

    第一个是 c.json 的,第二个是 b.json 的,第三个是 a.json 的。

    感谢阅读

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1246 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 144ms · UTC 18:15 · PVG 02:15 · LAX 11:15 · JFK 14:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.