时间同步+定时任务
一.为什么要时间同步?
| 场景 | 时间不准会出什么问题 |
|---|
| 日志分析 | 排查故障时看不准时间顺序 |
| HTTPS 证书 | 服务器时间偏差大,浏览器提示“证书无效” |
| JAVA项目登录 | JWT Token 验证失败,用户无法登录 |
| 分布式系统 | 多台服务器时间不一致,无法判断请求先后 |
二.chrony是什么
chrony是Linux系统的时间同步工具,让服务器时间保持准确
主要组件
| 组件 | 说明 |
|---|
| chronyd | 后台服务,持续同步时间(后台守护进程) |
| chronyc | 命令行工具,查看同步状态(命令工具) |
配置chrony.conf
cat > /etc/chrony.conf << 'EOF' # 使用中国区 NTP 服务器池(自动轮询,国内速度快) pool cn.pool.ntp.org iburst # 备用方案(任选其一,注释掉上面的 pool 即可使用) # server time1.aliyun.com iburst # server ntp.aliyun.com iburst # 允许内网客户端查询(作为时间服务器时启用) allow 192.168.0.0/16 # 记录系统时钟的晶振偏差,让 chrony 长期运行更精准 driftfile /var/lib/chrony/drift # 当偏差 > 1 秒时,在启动后的前 3 次同步中执行步进(跳转),之后只做缓慢微调 makestep 1.0 3 # 自动将系统时间写入硬件时钟(相当于定期执行 hwclock --systohc) rtcsync # NTP 认证密钥文件(一般用不到) keyfile /etc/chrony.keys # 调试转储目录(一般用不到) ntsdumpdir /var/lib/chrony # 闰秒时区设置(保持默认即可) leapsectz right/UTC # 日志目录 logdir /var/log/chrony #启动 systemctl enable --now chronyd
查看时间源
[root@gald ~]# chronyc sources -v .-- Source mode '^' = server, '=' = peer, '#' = local clock. / .- Source state '*' = current best, '+' = combined, '-' = not combined, | / 'x' = may be in error, '~' = too variable, '?' = unusable. || .- xxxx [ yyyy ] +/- zzzz || Reachability register (octal) -. | xxxx = adjusted offset, || Log2(Polling interval) --. | | yyyy = measured offset, || \ | | zzzz = estimated error. || | | \ MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^? time.neu.edu.cn 1 6 377 61 -1057s[ -1057s] +/- 9460us ^~ ntp.wdc2.us.leaseweb.net 3 6 377 58 -1057s[ -1057s] +/- 133ms ^? 119.28.183.184 2 6 377 61 -1057s[ -1057s] +/- 60ms ^? 139.199.214.202 2 6 377 61 -1057s[ -1057s] +/- 42ms
第一列——状态标识(最关键)
| 符号 | 当前行 | 含义 |
|---|
| ^? | 第一行 | 不可达,连不上 |
| ^- | 第二行 | 被否决(偏差较大,暂不使用) |
| ^* | 第三行 | 当前正在使用的主同步源 |
| ^+ | 第四行 | 备选同步源 |
chrony常用命令
#查看时间源 chronyc sources -v #立即同步 chronyc makestep #查看同步精度 chronyc tracking #查看时间 date #修改时区(改成亚洲/上海) timedatectl set-timezone Asia/shanghai #确认时区设置 timedatectl #手动修改配置 echo“Asia/shanghai” > /etc/timezone cp /user/share/zoneinfo/Asia/Shanghai /etc/localtime
二.定时任务
2.1什么是定时任务?
运维工作中经常需要在固定时间执行某些任务:每天凌晨备份日志、每小时清理临时文件、每周一发送报表……这些重复性工作可以用定时任务自动完成。
| 对比项 | Cron | Systemd Timer |
|---|
| 出现时间 | 传统(Unix时代) | 现代(Systemd时代) |
| 配置方式 | crontab文件 | .timer+.service单元 |
| 精度 | 分钟级 | 秒/微秒级 |
| 日志集成 | 需手动配置 | 自动集成journalctl |
| 依赖管理 | 不支持 | 支持 |
| 错过执行补偿 | 不支持 | 支 |
Cron是什么?
Cron是Linux系统中最经典的定时任务工具,通过crond守护进程每分钟检查一次是否有任务需要执行。
Cron三种配置位置
| 配置位置 | 用途 | 编辑方式 |
|---|
| crontab -e | 用户级定时任务 | 每个用户独立,保存再/var/spool/cron/用户名 |
| /etc/crontab | 系统级定时任务 | 需要root权限编辑 |
| /etc/cron.d | 应用级定时任务 | 每个应用独立文件,便于管理 |
Cron的时间字段格式
* * * * * 命令 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ └─── 星期几 (0-7, 0和7都表示周日) ┊ ┊ ┊ └───── 月份 (1-12) ┊ ┊ └─────── 日期 (1-31) ┊ └───────── 小时 (0-23) └─────────── 分钟 (0-59)
特殊字符
| 字符 | 含义 | 示例 |
|---|
| * | 任意值 | * * * * *每分钟 |
| , | 列举多个值 | 1,15,30 * * * * 每小时的第1,15,30分钟 |
| - | 范围 | 10-15* * * * 每小时的第10到15分钟 |
| / | 步长 | */5 * * * * 每五分钟 |
Systemd Timer
什么是Systemd Timer?
Systemd Timer 是 Systemd 内置的定时任务机制,由一个 .timer 单元(定义触发时间)和一个 .service 单元(定义执行内容)配对工作。
Timer的触发方式
| 触发方式 | 说明 | 示例 |
|---|
| OnCalendar | 日历触发,类似Cron的时间表达式 | --* 02:00:00每天凌晨两点 |
| OnBootSec | 系统启动后延迟触发 | OnBootSec=5min |
| OnUnitActiveSec | 服务上次激活后延迟触发 | OnUnitActiveSec=1h |
实战:每天凌晨备份日志(与Cron对比)
最小化安装后,没有tar.手动安装dnf -y install tar
第一步:创建备份脚本
#创建备份脚本 [root@gald ~]# cat > /opt/backup.sh <<'EOF' #!/bin/bash /usr/bin/tar -czf /backup/logs-timer-$(date +%F).tar.gz /var/log/ 2>/dev/null EOF #设置文件权限让所有用户都可以执行(也可以单独设置) [root@gald ~]# chmod +X /opt/backup.sh
第二步:创建Service单元
[root@magedu ~]# vim /etc/systemd/system/backup-timer.service [Unit] Description=Log Backup Service (Timer) #这里不是给程序使用可以不设置条件 [Service] Type=oneshot ExecStart=/opt/backup.sh #这里只能使用绝对路径 User=root #设置执行用户
Type=oneshot 表示任务执行一次即退出,适合定时任务
第三步:创建Timer单元
[root@gald ~]# vim /etc/systemd/system/backup-time.timer [Unit] Description=Log Backup Timer [Timer] OnCalendar=daily #启动设置 每天执行一次 Persistent=true #系统在计划时间关机,开机后立即执行(错过补偿) [Install] WantedBy=timers.target #定时单元
第四步:启动 Timer
[root@gald ~]# systemctl daemon-reload #每次写完system的文件都要使用 [root@gald ~]# systemctl enable backup-timer.timer #设置开机自动启动 [root@gald ~]# systemctl start backup-timer.timer #开启定时任务 [root@gald ~]# systemctl list-timers #查看所有的定时任务 NEXT LEFT LAST PASSED UNIT> Sat 2026-07-25 01:22:07 CST 59min Fri 2026-07-24 07:25:00 CST 59min ago dnf•makecache.timer> Sat 2026-07-25 01:30:34 CST 1h 8min Sat 2026-07-25 00:00:00 CST 22min ago fwupd•refresh.timer > Sat 2026-07-25 22:22:07 CST 21h Fri 2026-07-24 07:25:00 CST 2h 0min ago systemd•tmpfiles-clean.timer > Sun 2026-07-26 00:00:00 CST 23h - - backup•timer.timer > Sun 2026-07-26 00:08:39 CST 23h Sat 2026-07-25 00:21:53 CST 19s ago logrotate.timer> Mon 2026-07-27 01:38:13 CST 2 days Wed 2026-07-22 19:05:49 CST - fstrim.timer> 6 timers listed. Pass --all to see loaded but inactive timers, too.
| 字段 | 值 | 含义 |
|---|
| NEXT | Sun 2026-07-26 00:00:00 CST | 下次执行时间() |
| LEFT | 23h | 还要约23小时 |
| LAST | - | 从未执行过 |
| PASSED | - | 从未执行过 |
Cron和Systemd对比
| 对比项 | Cron | Systemd Timer |
|---|
| 生成的备份文件 | /backup/log-cron-日期.tar.gz | /backup/log-timer-日期.tar.gz |
| 配置方式 | 一行crontab | 两个单元文件 |
| 日志查看 | tail -f /var/log/cron | journalctl -u backup-timer.service |
| 适合场景 | 简单任务 | 复杂任务 |
OnCalendar时间表达式
| 表达式 | 含义 |
|---|
| daily | 每天 00:00:00 |
| weekly | 每周一 00:00:00 |
| monthly | 每月1号 00:00:00 |
| hourly | 每小时整点 |
| boot | 系统启动时 |
| --* 02:00:00 | 每天凌晨2点 |
| Mon..Fri 09:00:00 | 工作日上午9点 |
| * - - *-01 04:00:00 | 每月1号凌晨4点 |
| *:15:00 | 每十五分钟执行一次 |
选型建议
| 场景 | 推荐方案 | 原因 |
|---|
| 简单单条命令 | Cron | 配置简单,一行搞定 |
| 日常运维脚本 | Cron | 习惯使然,够用 |
| 需要依赖其他服务 | Systemd Timer | 可指定After= |
| 需要详细日志追踪 | Systemd Timer | 自动集成journalctl |
| 需要秒级精度 | Systemd Timer | Cron 只能到分钟 |
| 需要错过执行补偿 | Systemd Timer | Persistent=true |
Rocky 与 Ubuntu 的定时任务差异
| 对比项 | Rcoky10 | Ubuntu26.04 |
|---|
| crond 服务名 | crond | cron |
| 查看cron日志 | /var/log/cron | /var/log/syslog(grep cron) |
| systemctl 命令 | 同左 | 同左 |
| journalctl 命令 | 同左 | 同左 |