资讯动态

linux学习10:systemd timer(服务)替代 crontab(定时任务)

发布时间:2026/8/27 9:40:18 来源:尧图企业网站定制
systemd timer​ —— 替代 crontab(定时计划socket 激活​ —— 按需懒加载服务一、systemd timer 替代 crontab为什么不用 cron cronsystemd timer执行失败你不知道✅ 失败有日志systemctl status能看到任务重叠跑你不知道✅ 默认不会重叠可配置没有执行历史✅journalctl完整记录不能随机延迟✅ 内置RandomizedDelaySec不能按系统启动后多久触发✅ 支持OnBootSec精度分钟级✅ 秒级精度不能依赖其他服务✅After、Wants随便配一句话timer 是带日志、带状态、带依赖的 cron。核心概念只有两个东西xxx.timer → 定义service什么时候跑 xxx.service → 定义跑什么内容timer 只是触发器真正干活的是 service服务。一个最简单的例子每天凌晨备份1️⃣ 写 service服务定义内容/etc/systemd/system/backup.service[Unit] DescriptionDaily Backup [Service] Typeoneshot ExecStart/opt/scripts/backup.sh[Unit]区块基本描述注意Typeoneshot​ 是 timer 触发型 service 的标准写法跑完就退。2️⃣ 写 timer定时启动service/etc/systemd/system/backup.timer[Unit] DescriptionRun backup daily at 2am [Timer] OnCalendar*-*-* 02:00:00 Persistenttrue RandomizedDelaySec300 [Install] WantedBytimers.target[Unit]区块基本描述[Timer]区块定时规则与行为[Install]区块开机自启设置3️⃣ 启用systemctl daemon-reload systemctl enable --now backup.timerTimer 时间语法大全OnCalendar最常用写法含义*-*-* 02:00:00每天 2:00Mon *-*-* 03:00:00每周一 3:00*-*-01 00:00:00每月 1 号*-01~01 00:00:00每月最后一天*-*-* *:00:00每小时整点*-*-* *:*:00每分钟Mon..Fri 09:00:00工作日 9 点09:00简写每天 9:00支持时区OnCalendarTZAsia/Shanghai *-*-* 02:00:00 其他触发器cron 做不到的指令含义OnBootSec5min系统启动后 5 分钟OnStartupSec1hsystemd 启动后 1 小时OnUnitActiveSec7d上次执行完后 7 天再跑OnUnitInactiveSec1h上次停止后 1 小时再跑组合使用[Timer] OnBootSec10min OnUnitActiveSec1h→ 启动后 10 分钟跑一次之后每 1 小时跑一次。其他关键参数参数作用推荐值Persistenttrue系统关机期间错过的任务开机后补跑✅ 必开RandomizedDelaySec300随机延迟最多 5 分钟防惊群✅ 推荐AccuracySec1min精度窗口默认 1min可改 1s按需Unitxxx.service指定触发的 service默认同名一般省略日常操作命令# 看所有 timer 的状态 systemctl list-timers # 输出示例 # NEXT LEFT LAST PASSED UNIT # Mon 2026-08-25 02:00:00 CST 14h left Sun 2026-08-24 02:00:01 CST 9h ago backup.timer # 看某个 timer 下次触发时间 systemctl status backup.timer # 手动触发立即跑一次不等 timer systemctl start backup.service # 看执行历史 journalctl -u backup.service -blist-timers里LEFT​ 列直接告诉你还有多久跑——比 crontab 直观 100 倍。实战替代 crontab 的 logrotate原来 cron 里0 3 * * * /usr/sbin/logrotate /etc/logrotate.conf改成 timer/etc/systemd/system/logrotate.timer[Timer] OnCalendar*-*-* 03:00:00 Persistenttrue RandomizedDelaySec600 [Install] WantedBytimers.target/etc/systemd/system/logrotate.service[Service] Typeoneshot ExecStart/usr/sbin/logrotate /etc/logrotate.conf二、socket 激活按需懒加载是什么服务平时不跑有请求进来才启动处理完可以再退出。类似inetd / xinetd 的思路云函数的冷启动模式客户端连接 :8080 ↓ systemd 已经在监听 socket ↓ systemd 启动 myapp.service ↓ 把已建连的 socket 交给 myapp ↓ myapp 处理请求为什么要用好处说明 省内存不用的服务不占资源⚡ 启动快socket 已就绪客户端不超时 方便升级重启服务连接不中断 减少攻击面不用的端口没有进程在跑实战让一个 Python HTTP 服务按需启动1️⃣ 写 service/etc/systemd/system/myapp.service[Unit] DescriptionOn-demand Python App Requiresmyapp.socket [Service] Typesimple ExecStart/usr/bin/python3 /opt/myapp/server.py # 关键systemd 会把监听 fd 传给程序 # Python 用 systemd.daemon.listen_fds() 接收 StandardInputsocket [Install] WantedBymulti-user.target2️⃣ 写 socket 单元/etc/systemd/system/myapp.socket[Unit] DescriptionSocket for myapp [Socket] ListenStream9090 Acceptno # no 单进程处理所有连接yes 每个连接 fork 一个 [Install] WantedBysockets.target3️⃣ 启用 socket不是 servicesystemctl daemon-reload systemctl enable --now myapp.socket⚠️ 注意enable 的是.socket不是.service。service 由 socket 自动拉起。4️⃣ 验证# socket 在监听但 service 没跑 ss -tlnp | grep 9090 systemctl status myapp.service # → inactive (dead) ✅ # 用 curl 打一下 curl http://localhost:9090 # 再看 service systemctl status myapp.service # → active (running) ✅关键参数说明socket 单元参数说明ListenStreamTCP 端口ListenDatagramUDP 端口ListenUnixStreamUnix socket 路径Acceptno单实例服务推荐Acceptyes每连接一个实例类似 inetdSocketUser/SocketGroupsocket 文件权限MaxConnections最大排队连接数Service指定对应的 service默认同名service 单元参数说明StandardInputsocket把连接 fd 作为 stdinRequiresxxx.socket声明依赖程序侧怎么接收 socket fdPython 示例from systemd.daemon import listen_fds import socket fds listen_fds() if fds: sock socket.fromfd(fds[0], socket.AF_INET, socket.SOCK_STREAM) else: # 非 socket 激活模式自己 bind sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((0.0.0.0, 9090)) sock.listen(10) conn, addr sock.accept() # 处理请求...大多数现代框架Go net/http、Node.js、Python gunicorn都原生支持​ systemd socket 激活不需要自己写 fd 接收代码。真实场景sshd 的 socket 激活很多发行版现在 sshd 默认就是 socket 激活systemctl status sshd.socket # → 监听 22 端口 # 有人连 SSH → 自动拉起 sshd.service好处平时 sshd 不占内存而且 systemd 可以限制连接频率防暴力破解。socket 激活 timer 组合技socket 激活 → 按需启动服务 timer → 空闲超时自动停掉服务service 里加[Service] ExecStart/opt/myapp/server # 空闲 5 分钟自动退出 ExecStopPost/bin/sh -c sleep 300 systemctl is-active myapp || systemctl stop myapp或者用 systemd 的RuntimeMaxSec[Service] RuntimeMaxSec5min # 最多跑 5 分钟就停三、排错速查timer socket问题命令timer 没触发systemctl list-timers看 NEXTtimer 触发了但 service 失败journalctl -u xxx.servicesocket 端口没监听systemctl status xxx.socketsocket 激活后 service 没拉起journalctl -u xxx.service -b程序收不到 fd确认StandardInputsocket 程序支持enable 了但重启不生效确认WantedBysockets.target或timers.target四、什么时候该用哪个场景用 timer用 socket 激活定时备份✅日志轮转✅数据同步✅证书续期✅低流量内部 API✅管理后台偶尔访问✅SSH✅系统默认高并发 Web 服务❌常驻更好数据库❌必须常驻

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价