systemd&&定时任务

2348 字
12 分钟
systemd&&定时任务
systemd&&定时任务

systemd&&定时任务#

[TOC]


systemctl#

在Linux系统(特别是Centos7)中对服务进行启动、关闭、重启的操作使用sytemctl

  • systemctl start xx

  • systemctl stop xx

  • systemctl restart xx

  • systemctl status xx

  • systemctl reload xx

Terminal window
状态查询命令:
[root@Rocky10 ~]# systemctl status sshd
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-03-06 09:12:51 CST; 7h ago
Invocation: 982b5a7bcc964c5f99bc720ec3a786d4
Docs: man:sshd(8)
man:sshd_config(5)
=======================================
'更方便的判断!'
root@rocky10:~# systemctl is-(tab补齐)
is-active is-enabled....
(1)验证服务是否处于活动状态
[root@Rocky10 ~]# systemctl is-active sshd
active
(2)验证单元是否处于开机自启状态!
[root@Rocky10 ~]# systemctl is-enabled sshd
enabled
=======================================
'列出当前系统所有正在活跃的服务'
[root@Rocky10 ~]# systemctl list-units --type=service --state=active
UNIT LOAD ACTIVE SUB DESCRIPTION
accounts-daemon.service loaded active running Accounts Service
alsa-state.service loaded active running Manage
atd.service loaded active running Deferred
auditd.service loaded active running Security
..............
=======================================
'列出当前系统所有设置为开机自启的服务'
[root@Rocky10 ~]# systemctl list-unit-files --type=service --state=enabled
UNIT FILE STATE PRESET
accounts-daemon.service enabled enabled
atd.service enabled enabled
audit-rules.service enabled enabled
auditd.service enabled enabled
..............
=======================================
'屏蔽与取消屏蔽:'
systemctl mask name.service
# 屏蔽服务
(创建指向/dev/null的链接,阻止启动)
systemctl unmask name.service
# 取消屏蔽服务
⚠️注意:disable的服务可手动启动,mask的服务则完全无法启动
[root@Rocky10 ~]# ps -ef | grep crond
root 1417 1 0 09:12 ? 00:00:00 /usr/sbin/crond -n
# 定时任务服务!
[root@Rocky10 ~]# systemctl mask crond
Created symlink '/etc/systemd/system/crond.service' → '/dev/null'.
# 定向到空!
[root@Rocky10 ~]# systemctl start crond
Failed to start crond.service: Unit crond.service is masked.
# 屏蔽后,无法手动启动!
[root@Rocky10 ~]# systemctl unmask crond
Removed '/etc/systemd/system/crond.service'.
[root@Rocky10 ~]# systemctl is-active crond
active

服务单元结构#

systemd 使用 unit 文件 来管理系统资源

常见的 unit 类型包括:

  • .service:定义一个服务(进程)
  • .timer:定义定时器(类似 cron,但更强大)
  • .socket:用于 socket 激活(按需启动服务)
  • .target:类似于运行级别(如 multi-user.target)
  • …

所有 unit 文件通常放在 以下目录(按优先级从高到低):

  1. /etc/systemd/system/ - 管理员自定义配置(最高优先级)
  2. /run/systemd/system/ - 运行时生成的配置
  3. /usr/lib/systemd/system/ - 系统默认配置
Terminal window
'如何启停服务'
假设你有一个名为 myapp.service 的服务:
systemctl restart myapp.service
....
# 参考上面的笔记!
⚠️注意:.service 后缀可省略
================================================
systemctl start myapp 等价于 start myapp.service
================================================
如果你是通过,编译安装Nginx,而且没有通过yum安装
那么你不能够通过systemctl进行管理,比如服务的启动,暂停...
必须手动书写服务的配置、格式如下!!!
Terminal window
'单元文件结构'
[Unit]
# 主要用于定义服务的依赖关系和描述信息!
Description=服务描述
After=network.target remote-fs.target
# 定义启动顺序(此服务在指定目标之后启动)
Before=xxx
# 在某个 unit 启动之前启动本unit
Requires=依赖服务.service
# 强依赖(依赖服务必须成功启动)
# 若依赖项失败,本 unit 也失败
Wants=依赖服务.service
# 弱依赖,即使依赖项失败,本 unit 仍尝试启动
[Service]
Type=forking|simple|oneshot|notify
# 服务类型
ExecStart=/usr/sbin/服务名
# 启动命令
ExecReload=/bin/kill -s HUP $MAINPID
# 重载配置命令
ExecStop=/bin/kill -SIGTERM $MAINPID
# $MAINPID 是一个 systemd 变量,它代表服务的主进程ID
# 这条命令的作用是向主进程发送一个标准的终止信号
# 这是停止服务的正确方式
PIDFile=/run/服务名.pid
# 可以用一个文件来记录服务的pid
Restart=on-failure
# 什么时候重启?
# 仅非正常退出时重启(退出码非 0、被信号终止、超时等)
# 手动 systemctl stop,它不会重启!
TimeoutStopSec=5
# 停止服务的超时时间
# 最多等待 5 秒,如果 5 秒后进程仍未退出,systemd 将强制杀死它
[Install]
WantedBy=multi-user.target
# 控制服务在什么系统运行级别(target)下自动启动
# 当系统进入这个运行级别时,会自动启动本服务
'大多数运行级别为3即可'

Restart=always vs Restart=on-failure

策略行为适用场景
always任何退出都重启(包括正常退出 exit 0、手动 stop、崩溃等)守护进程型服务(如数据库、Web 服务),希望始终运行
on-failure仅非正常退出时重启(退出码非 0、被信号终止、超时等)脚本/批处理任务,希望失败时重试,正常完成则不重启

👑实验案例#

编写一个简单的 service 单元(执行脚本)

  • 场景:每天都输出 当前时间 到 /home/test.txt
/server/sh/log-time.sh
步骤 1:创建脚本
[root@R11 sh]# pwd
/server/sh
[root@R11 sh]# vim log-time.sh
#!/bin/bash
echo "$(date): Hello from systemd timer!" >> /home/test.txt
[root@R11 sh]# chmod +x log-time.sh
[root@R11 sh]# ll log-time.sh
-rwxr-xr-x 1 root root 72 Mar 14 16:28 log-time.sh
步骤 2:创建 service 文件
/etc/systemd/system/log-time.service
================
!注意是service并不是server
================
[root@R11 sh]# vim /etc/systemd/system/log-time.service
[Unit]
# 服务描述
Description=time to /home/test.txt
[Service]
# oneshot:跑一次就退出,正好匹配"跑完就退"的脚本
Type=oneshot
# 执行脚本(绝对路径)
ExecStart=/server/sh/log-time.sh
# User=www
# Group=www
# !前提是这个用户得有权限!
# 可选:指定运行用户(避免 root 写文件)
# ⚠️ 不加 [Install] 段:开机自启的是 timer,不是 service
# service 是被动激活的(由 timer 触发),不用 enable
[root@R11 sh]# ll /etc/systemd/system/log-time.service
-rw-r--r-- 1 root root 178 Mar 14 16:34 /etc/systemd/system/log-time.service
步骤 3:创建对应的 timer 文件
/etc/systemd/system/log-time.timer
✅ 关键规则:.timer 文件名必须与 .service 文件名前缀一致
# (即 log-time.timer 对应 log-time.service)
[root@R11 sh]# vim /etc/systemd/system/log-time.timer
[Unit]
# timer 强依赖同名 service
Description=Run log-time.service every day
Requires=log-time.service
[Timer]
# 每天运行一次(默认通常是午夜 00:00)
# 或更精确:OnCalendar=*-*-* 02:00:00
OnCalendar=daily
# 错过触发时间(如关机/休眠),系统启动后立即补执行一次
Persistent=true
# 触发目标(默认就是同名 service,显式写出更清晰;文件名不一致时可用 Unit= 指定)
Unit=log-time.service
[Install]
# 开机自启的是 timer(触发器),不是 service
WantedBy=timers.target
步骤 4:启用并启动 timer
[root@R11 sh]# systemctl daemon-reload
# 重载 systemd 配置
[root@R11 sh]# systemctl enable --now log-time.timer
# 启用并启动 timer
⚠️ 不要手动 start log-time.service,它应由 timer 触发
# 这里启动的是.timer
[root@R11 sh]# systemctl status log-time.timer
● log-time.timer - Run log-time.service every day
Loaded: loaded (/etc/systemd/system/log-time.timer; enabled; preset: disabled)
Active: active (waiting) since Sat 2026-03-14 16:58:43 CST; 15s ago
Invocation: 6f95ba8ec5044123abb448cdd024a5e3
Trigger: Sun 2026-03-15 00:00:00 CST; 7h left
Triggers: ● log-time.service
Mar 14 16:58:43 R11 systemd[1]: Started log-time.timer - Run log-time.service every day
[root@R11 sh]# ll /home/
total 0
[root@R11 sh]# systemctl restart log-time.timer
[root@R11 sh]# journalctl -u log-time.service | tail -3
# 查看指定服务的日志
Mar 14 18:03:47 R11 systemd[1]: Starting log-time.service - time to /home/test.txt...
# 启动服务..
Mar 14 18:03:47 R11 systemd[1]: log-time.service: Deactivated successfully.
Mar 14 18:03:47 R11 systemd[1]: Finished log-time.service - time to /home/test.txt.
# 成功写入!!
[root@R11 sh]# ll /home/
total 4
-rw-r--r-- 1 root root 177 Mar 14 18:03 test.txt
# 重启完timer服务就会手动执行一次定时任务
[root@R11 sh]# cat /home/test.txt
Sat Mar 14 06:03:47 PM CST 2026: Hello from systemd timer!

OnCalendar#

OnCalendar 支持类似 cron 的语法,但更灵活:

示例含义
daily每天 00<00>
hourly每小时
*-*-* 14:30:00每天 14<30>
Mon..Fri *-*-* 09:00:00工作日上午 9 点
*/5:00每 5 分钟
*:0/5每 5 秒
Terminal window
[root@R11 sh]# systemctl list-timers
# 查看所有的定时任务
NEXT LEFT LAST PASSED UNIT
.........
Sun..03-15 00:00 6h 2026-03-14.. - log-time.timer
列名(关键字)含义说明
NEXT下一次定时器将触发的时间
LEFT距离下一次触发还剩余的时间(例如 “6h” 表示还有 6 小时)
LAST上一次定时器实际触发的时间
PASSED自上一次触发以来已经过去的时间(例如 “2min ago”)、若尚未触发过,则显示 - 或留空
UNIT对应的定时器单元名称(以 .timer 结尾),它控制一个关联的 .service 单元
Terminal window
# 也可以通过修改时间进行触发!
# 下一次触发的时间在03-15 00:00:00
[root@R11 sh]# tail -1 /home/test.txt
Sat Mar 14 06:03:47 PM CST 2026: Hello from systemd timer!
[root@R11 sh]# date
Sat Mar 14 06:10:50 PM CST 2026
# 现在的时间⌚️
[root@R11 sh]# date -s "2026-03-14 23:59:50"
Sat Mar 14 11:59:50 PM CST 2026
# 手动修改
[root@R11 sh]# tail -1 /home/test.txt
Sat Mar 14 06:03:47 PM CST 2026: Hello from systemd timer!
[root@R11 sh]# tail -1 /home/test.txt
Sat Mar 14 06:03:47 PM CST 2026: Hello from systemd timer!
# 我又查了几次,还是没有写入、此时我有点怀疑我自己了已经!
[root@R11 sh]# date
Sun Mar 15 12:00:15 AM CST 2026
# 又看了眼时间!已经过00:00:00了呀!
[root@R11 sh]# journalctl -u log-time.service | tail -3
Mar 14 18:03:47 R11 systemd[1]: Starting log-time.service - time to /home/test.txt...
Mar 14 18:03:47 R11 systemd[1]: log-time.service: Deactivated successfully.
Mar 14 18:03:47 R11 systemd[1]: Finished log-time.service - time to /home/test.txt.
# 又看了眼日志,还是上次的日志呀!!
[root@R11 sh]# systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
....
Mon 2026-03-16 00:00:00 CST 23h Sun 2026-03-15 00:00:27 CST 17s ago log-time.timer log-time.service
# 但是你看下一次执行的时间已经变了!变成03-16了
# 下一次执行触发的时间要23个小时
# 上一次触发的时间为03-15 00:00:27
'说明它是执行过的呀!'
[root@R11 sh]# tail -1 /home/test.txt
Sun Mar 15 12:00:27 AM CST 2026: Hello from systemd timer!
# 又cat了一次终于出来了!
[root@R11 sh]# journalctl -u log-time.service | tail -3
Mar 15 00:00:27 R11 systemd[1]: Starting log-time.service - time to /home/test.txt...
Mar 15 00:00:27 R11 systemd[1]: log-time.service: Deactivated successfully.
Mar 15 00:00:27 R11 systemd[1]: Finished log-time.service - time to /home/test.txt.
# 又看了一眼日志,也是成功运行了起来!
'那么如何把时间改回✅️正确的呢?'
[root@R11 sh]# date
Sun Mar 15 12:09:07 AM CST 2026
[root@R11 sh]# systemctl restart chronyd
# 静静地等待一会ing
.........
[root@R11 sh]# date
Sun Mar 15 12:09:27 AM CST 2026
[root@R11 sh]# date
Sat Mar 14 06:21:06 PM CST 2026
# 变回来了,下午六点半
Note

💡 手动改时间后,timer 触发有延迟

date -s 改到 00<00> 后,timer 直到 00:00<27> 才触发(journalctl 里时间戳是 00:00:27) 因为手动改时间后,systemd 需要先检测到时间跳变,timer 才会重新计算触发,不是立即触发 这是正常现象,稍等几十秒即可,别急着”怀疑自己”

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

相关文章智能推荐
1
K8s故障排查 & 控制器与Service实战
Kubernetes故障排查三板斧describe/logs/exec与command&args,容器三种状态与pause基础架构容器,env环境变量部署WordPress,Deployment副本控制与滚动更新回滚,Service四类型ClusterIP/NodePort/LoadBalancer/ExternalName,kube-proxy+iptables底层实现,名称空间,CoreDNS服务发现与跨ns解析,deploy+svc部署WordPress及跨名称空间连库实战
2
K8s开篇 & kubeadm集群部署实战
KubernetesK8s核心概念与架构详解,基于kubeadm从零部署高可用集群,Flannel网络配置,Pod基础使用与YAML声明式管理
3
Prometheus 告警 && etcd 集群实战
Prometheus监控Alertmanager 告警路由/模板/静默/抑制 + 钉钉插件,etcd 3.7 TLS 高可用集群部署/备份恢复/Prometheus 监控,复用既有 kpyun CA 体系
4
Prometheus存储实战 && HTTPS认证 && 黑盒监控
Prometheus监控VictoriaMetrics单机部署+remote_write远端存储,Prometheus启用HTTPS+Basic Auth认证,node-exporter黑白名单,标签管理(relabel/metric_relabel),blackbox-exporter HTTP/ICMP/TCP黑盒探测,Grafana存储迁移到MySQL
5
Prometheus自定义监控 && 服务发现 && 联邦模式
Prometheus监控部署 pushgateway 实现短期任务/自定义指标的推送式监控(API 推送删除、honor_labels、TCP 12 状态、丢包率脚本),用 Go + client_golang 开发自定义 exporter(静态编译零依赖),落地 file_sd 与 consul 服务发现(consul 2.0.3 集群 + consul_exporter),最后用 3 台 Prometheus server 搭建联邦模式实现分布式采集汇总
Profile Image of the Author
久棹
不是先学好了再干,而是先干起来再学习,干中学!
分类
站点统计
文章
115
分类
15
标签
272
总字数
306,562
运行时长
0 天
最后活动
0 天前
文章目录