美文网首页
使用Systemd配置定时任务

使用Systemd配置定时任务

作者: aneirin | 来源:发表于2021-01-27 19:45 被阅读0次

    在Linux世界中,提到定时任务,第一个想到的肯定是Cron,其实Systemd也可以实现定时任务,相比较Cron,Systemd实现的定时任务有以下优点:

    • 可以限制任务使用CPU的额度,比如任务最多占用20%的CPU
    • 任务可以方便拆分,比如可以创建相互依赖的线性任务
    • 自动生成日志,配合Systemd的日志工具,方便查看和排错

    Timer units
    Systemd通过创建结尾为“.timer”的文件来创建定时任务,该文件用来控制指定的“.service”。Timer unit文件和Systemd其他的单元配置文件类似,唯一不同是文件中包含“[Timer]”,其用来定义什么时间和如何激活计时器,“Timer”有两种定义方式:

    • Realtime timers(即真实时间),Cron也是使用这种方式定义定时任务的执行时间。使用选项“OnCalendar=”来定义这种类型的Timer
    • Monotonic timers,相对于一个起始点指定一个时间段,过了这个时间段后激活计时器。在电脑关机的情况下这些计时器会停掉。有很多不同种类的“monotonic timers”,都包含“OnTypeSec=”,常用的有“OnBootSec”、“OnUnitActiveSec”。

    Service units
    每一个“.timer”文件必须有一个对应的“.service”文件存在,这样计时器才有意义。默认情况下,如果Timer和Service的文件名(不包含扩展名)相同,则“.timer”文件控制“.service”文件的运行,比如“foo.timer”和“foo.service”。当然文件名也可以不同,这时需要在“.timer”文件的“[Timer]”内配置“Unit”选项,将要控制的“.service”文件名写入即可。
    注意,“.service”不需要再包含“[Install]”,因为“.timer”文件已经包含了。

    单元管理的常用命令

    • systemctl start [UnitName] //启动单元
    • systemctl stop [UnitName] //关闭单元
    • systemctl restart [UnitName] //重启单元
    • systemctl kill [UnitName] //杀死单元进程
    • systemctl status [UnitName] //查看单元状态
    • systemctl enable [UnitName] //开机自动执行该单元
    • systemctl disable [UnitName] //关闭开机自动执行
    • systemctl list-unit-files //查看所有单元
    • systemctl list-unit-files --type service //查看所有service单元
    • systemctl list-unit-files --type timer //查看所有timer单元
    • systemctl list-timers //查看所有已启动的timer

    示例
    下面通过一个具体的例子,展示“monotonic timer”和“realtime timer”文件的配置
    (1)Monotonic timer
    系统启动15分钟后和每周都运行(这里是或的关系)
    /usr/lib/systemd/system/foo.timer

    [Unit]
    Description=Run foo weekly and on boot
    
    [Timer]
    OnBootSec=15min  
    OnUnitActiveSec=1w 
    
    [Install]
    WantedBy=timers.target
    

    (2)Realtime timer
    每周一的12:00 AM运行
    /usr/lib/systemd/system/foo.timer

    [Unit]
    Description=Run foo weekly
    
    [Timer]
    OnCalendar=weekly
    
    [Install]
    WantedBy=timers.target
    

    当需要更精确的时间控制,按照下面时间格式配置“OnCalendar”,

    DayOfWeek Year-Month-Day Hour:Minute:Second
    

    星号表示任何值,逗号用于隔开可能的值,使用“..”隔开的值表示一个连续范围。下面表示每个月头四天的“12:00 PM”且当天是星期一或星期二激活计时器。

    OnCalendar=Mon,Tue *-*-01..04 12:00:00
    

    关于“OnCalendar”更加详细的介绍可参考systemd.time(7)。
    (3)配置一个完整的例子,包含“.timer”文件和“.service”文件,展示Systemd中配置定时任务,
    /usr/lib/systemd/system/mytest.service

    [Unit]
    Description=MyTimer
    
    [Service]
    ExecStart=/tmp/echo-date.sh
    

    /usr/lib/systemd/system/mytest.timer

    [Unit]
    Description=Runs mytimer every minute
    
    [Timer]
    OnUnitActiveSec=1m
    
    [Install]
    WantedBy=multi-user.target
    

    /tmp/echo-date.sh,记得给该文件赋予可执行权限

    #!/bin/bash
    echo "$(date)" >> /tmp/output.txt
    

    配置完“mytest.service”和“mytest.timer”文件后,运行下面命令,

    sudo systemctl daemon-reload
    sudo systemctl start mytest.timer
    sudo systemctl start mytest.service
    

    查看“/tmp/output.txt”,内容如下:

    aneirin@host-1:$ cat /tmp/output.txt 
    Wed Jan 27 10:38:37 CST 2021
    Wed Jan 27 10:39:37 CST 2021
    

    总结
    本文对Systemd配置定时任务做了简单的介绍,它完全可以作为Cron的替代工具使用,但Timer也不是十全十美的,相对于Cron,它有两点不足:

    • 为了实现定时任务需要配置两个文件,而Cron仅需要一行
    • 发送邮件不方便,Cron有现成的发送邮件选项“MAILTO”

    最后,希望这篇文章能帮到正在努力的你,欢迎关注评论!

    相关文章

      网友评论

          本文标题:使用Systemd配置定时任务

          本文链接:https://www.haomeiwen.com/subject/myaazktx.html