☰
Day 10 Linux服务管理实战--systemd日志与时间同步
2026/10/11 5:54:29 网站建设 项目流程

Linux 服务管理实战:systemd、日志与时间同步的完整闭环

上一期我们讲了进程管理,能看清每个进程、能给它发信号。但手动kill+nohup管不了一台服务器上的几十个服务——谁负责开机自启?谁负责挂了自动拉起?谁来统一收集日志?答案都是 systemd。

本文以 Ubuntu 24.04 / Rocky 9 为演示环境,覆盖四块内容:systemd 到底管了什么、systemctl 全家桶、手写 service unit 并按四层验证、三大日志入口(journalctl / rsyslog / dmesg)逐层缩小排障窗口,最后是时间同步与 Chrony。

文章目录

  • Linux 服务管理实战:systemd、日志与时间同步的完整闭环
    • 一、systemd 到底管理了什么
    • 二、systemctl:服务管理的瑞士军刀
      • 2.1 生命周期五连
      • 2.2 开机自启三连
      • 2.3 status 输出逐行读
      • 2.4 排障常用的几个
    • 三、daemon-reload:最容易漏的一步
    • 四、手写一个 service unit
      • 4.1 完整模板(逐字段注释)
      • 4.2 Type 怎么选
      • 4.3 Restart 策略
      • 4.4 四层验证:Unit → 进程 → 端口 → 应用
    • 五、故障证据去哪找:三个日志入口
    • 六、tail:文件日志的入门神器
    • 七、journalctl:把排障窗口逐层缩小
      • 7.1 基础用法
      • 7.2 verbose 模式:看到日志的全部字段
      • 7.3 核心思路:五层条件逐层缩小窗口
    • 八、dmesg:内核在说什么
    • 九、系统时间、时区与 Chrony
      • 9.1 先看清现状
      • 9.2 时区设置
      • 9.3 为什么必须做时间同步
      • 9.4 Chrony:现代时间同步方案
    • 十、总结

一、systemd 到底管理了什么

systemd 是现代 Linux 的1 号进程(PID 1)——内核启动后运行的第一个用户态程序,其他所有进程都直接或间接由它拉起。它管的东西远不止"服务":

ps-p1-opid,comm# PID COMMAND# 1 systemd

它管理的基本单位叫 Unit(单元),常见类型:

类型后缀管什么例子
service.service服务进程(最常用)nginx.service
target.target一组 unit 的集合(类似"运行级别")multi-user.target
socket.socket按需启动(收到连接才拉起服务)sshd.socket
timer.timer定时任务(cron 的替代品)logrotate.timer
mount.mount文件系统挂载点-.mount(根分区)

两个容易忽略但很值钱的知识点:

  1. 开机自启:以前的/etc/rc.local、chkconfig 全被 systemd 收编,自启就是"把服务挂到某个 target 下"。
  2. 资源控制:systemd 依托 cgroups 给每个服务记账(CPU、内存、进程数),systemd-cgtop可以像 top 一样按服务看资源——这是按进程看资源的 ps/top 之外的另一个维度。

二、systemctl:服务管理的瑞士军刀

2.1 生命周期五连

sudosystemctl start nginx# 启动sudosystemctl stop nginx# 停止sudosystemctl restart nginx# 重启(先停再起,有瞬断)sudosystemctl reload nginx# 重读配置(不断服务,需服务支持)sudosystemctl status nginx# 看状态(最常用)

restart 和 reload 的区别必须分清:restart 是"杀掉重来",服务会短暂不可用;reload 是"让进程重读配置文件",进程不换、连接不断——线上改配置优先 reload。

2.2 开机自启三连

sudosystemctlenablenginx# 设开机自启sudosystemctl disable nginx# 取消开机自启systemctl is-enabled nginx# 查询是否自启

高频易错点:enable只管开机自启,不会立刻启动服务;start只管现在启动,不管开机。两个都要?一条命令搞定:

sudosystemctlenable--nownginx# 自启 + 立刻启动sudosystemctl disable--nownginx# 取消自启 + 立刻停止

2.3 status 输出逐行读

systemctl status nginx
● nginx.service - A high performance web server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled) Active: active (running) since Sat 2026-10-10 09:00:01 CST; 2h ago Main PID: 1000 (nginx) Tasks: 3 (limit: 4561) Memory: 5.2M CPU: 120ms CGroup: /system.slice/nginx.service ├─1000 nginx: master process └─1001 nginx: worker process
  • Loaded:unit 文件路径;enabled说明设了自启
  • Active:active (running)正常运行;failed出事了;inactive (dead)没在跑
  • Main PID:主进程号
  • CGroup:该服务名下的所有进程——僵尸进程的爹、被服务拉起的子进程,全在这一览无余

2.4 排障常用的几个

# 只看挂了的服务(宕机排查第一步)systemctl--failed# 服务为什么起不来?看它自己的报错systemctl status nginx# 看服务的标准错误输出journalctl-unginx-e# -e 直接跳到末尾(下一章详讲)# 禁止一个服务被任何东西(包括依赖)拉起sudosystemctl mask nginxsudosystemctl unmask nginx

mask是"钉死":disable 之后其他服务仍可能把它拉起来,mask 直接把 unit 文件软链到/dev/null,谁也启动不了它——处理流氓服务的终极手段。


三、daemon-reload:最容易漏的一步

sudosystemctl daemon-reload

它做什么:让 systemd 重新读取磁盘上的 unit 配置文件。

为什么需要:你直接vim修改了/etc/systemd/system/xxx.service,systemd并不知道——它内存里还是旧配置。此时执行restart会出现经典警告:

Warning: The unit file, source configuration file or drop-ins of xxx.service changed on disk. Run 'systemctl daemon-reload' to reload units.

标准动作顺序(改配置的肌肉记忆):

sudovim/etc/systemd/system/myapp.service# 1. 改 unit 文件sudosystemctl daemon-reload# 2. 让 systemd 重新读sudosystemctl restart myapp# 3. 按新配置重启systemctl status myapp# 4. 验证

反过来,daemon-reload只重读配置,不重启服务——它管"菜单",不管"菜"。漏掉第 2 步是新手部署自己写的服务时"改了配置不生效"的第一大原因。


四、手写一个 service unit

4.1 完整模板(逐字段注释)

假设我们有个自己写的 SpringBoot 应用/opt/myapp/app.jar,要交给 systemd 托管:

sudovim/etc/systemd/system/myapp.service
[Unit] Description=My SpringBoot App # 描述,status 里显示的标题 After=network-online.target # 排序:网络就绪之后再启动我 Wants=network-online.target # 弱依赖:尽量把网络拉起来(拉不起来也不拦着我) [Service] Type=simple # 主进程就是前台进程(java 不 fork 时用 simple) ExecStart=/usr/bin/java -jar /opt/myapp/app.jar # 怎么启动(必须绝对路径) ExecReload=/bin/kill -HUP $MAINPID # reload 时执行什么 Restart=on-failure # 崩溃自动拉起(核心!) RestartSec=5 # 拉起前等 5 秒,防止疯狂重启 User=appuser # 用哪个用户跑(别用 root) WorkingDirectory=/opt/myapp # 工作目录 Environment=JAVA_OPTS=-Xmx512m # 环境变量 [Install] WantedBy=multi-user.target # 挂到"多用户模式"下 → 开机自启

三个区块的职责一句话:[Unit] 讲关系(我是谁、排在谁后面)、[Service] 讲怎么跑(启动命令、重启策略)、[Install] 讲挂哪(挂到哪个 target 实现自启)。

4.2 Type 怎么选

Type含义适用
simpleExecStart 的进程就是主进程,前台跑java -jar、python app.py
forking进程会 fork 出子进程然后父进程退出nginx(传统 daemon 行为)
notify服务自己通知 systemd"我就绪了"支持 sd_notify 的现代服务

4.3 Restart 策略

  • no(默认):挂了就挂了
  • on-failure:非正常退出就自动拉起(推荐)
  • always:不管怎么退出都拉起(连正常 stop 后也会被拉回,慎用)

这就是上一期预告的"崩溃自愈":半夜 3 点服务崩了,systemd 在你睡觉时已经把它拉起来了,你早上只在日志里看到一次重启记录。

4.4 四层验证:Unit → 进程 → 端口 → 应用

服务部署完,别只看 status 绿了就走人,按四层逐级验证:

第 1 层:Unit 层(systemd 眼中)

systemctl status myapp# Active: active (running)?systemctl is-enabled myapp# enabled(开机自启)?

第 2 层:进程层(内核眼中)

pgrep-a-fapp.jar# 进程在跑?PID 和 Main PID 一致?

第 3 层:端口层(网络眼中)

ss-tlnp|grep8080# 端口在监听?进程名对得上?

第 4 层:应用层(用户眼中)

curl-Ihttp://localhost:8080/actuator/health# HTTP/1.1 200 —— 这才是"服务真的能用了"

四层各回答一个问题:systemd 认为它活着吗?进程真的存在吗?网络真的通了吗?用户真的能访问吗?——任何一层断了,故障范围立刻锁定。


五、故障证据去哪找:三个日志入口

服务挂了别瞎猜,Linux 的日志分三个入口,按故障类型选对入口,排障效率翻倍:

入口看什么工具
journalctlsystemd 管的所有服务日志(含开机过程)journalctl -u xxx
/var/log/rsyslog 落盘的传统日志文件tail -f、grep
dmesg内核与硬件(磁盘报错、OOM 杀进程)dmesg -T

选路口诀:

  • 服务起不来 / 应用报错→journalctl -u 服务名
  • 登录失败 / 认证问题→/var/log/auth.log(Rocky 为/var/log/secure)
  • 机器卡死 / 磁盘报错 / 进程被杀→dmesg,重点搜OOM、I/O error

六、tail:文件日志的入门神器

# 看文件末尾 100 行tail-n100/var/log/syslog# 持续盯着日志滚动(排障时最常用)tail-f/var/log/nginx/error.log# 文件被轮转切割后依然盯着新文件(比 -f 更稳)tail-F/var/log/nginx/access.log# 同时盯多个文件(用 ==> 分隔)tail-fapp.log error.log# 配合 grep 只看关心的行tail-f/var/log/nginx/access.log|grep" 500 "

-f和-F的区别:日志按天/大小切割时(access.log→access.log.1+ 新的access.log),-f还死盯着旧文件的句柄,新日志一条也看不到;-F会自动跟到新文件。盯被 logrotate 管理的日志,用-F。


七、journalctl:把排障窗口逐层缩小

journalctl 读的是 systemd 的日志(journal),它最大的价值是结构化——每条日志都带时间、Unit、PID、优先级等字段,可以像查数据库一样过滤。

7.1 基础用法

journalctl# 全部日志(一般不这么干,量太大)journalctl-unginx# 只看 nginx 这个服务journalctl-unginx-f# 持续盯着滚动(类似 tail -f)journalctl-unginx-n50# 只看最近 50 行journalctl-unginx-e# 直接跳到末尾,看最新报错

7.2 verbose 模式:看到日志的全部字段

journalctl-unginx-overbose

输出会展开每条日志的所有元数据字段:

Sat 2026-10-10 09:00:01 CST ... _PID=1000 _UID=0 _COMM=nginx _SYSTEMD_UNIT=nginx.service PRIORITY=6 ...

这些下划线开头的字段(_PID、_UID、_SYSTEMD_UNIT)都可以作为后续的过滤条件——这就是下一节"字段过滤"的素材来源。

7.3 核心思路:五层条件逐层缩小窗口

故障排查的本质是缩小搜索范围。journalctl 按这五层从粗到细切:

① boot(哪次开机)→ ② 时间(哪段时间)→ ③ Unit(哪个服务) → ④ 级别(多严重)→ ⑤ 字段(哪个进程/用户)

第 ① 层:按开机次序

journalctl-b# 本次开机以来的日志journalctl-b-1# 上一次开机的日志(重启后查"重启前发生了什么")journalctl --list-boots# 列出所有开机记录,带编号和时间

机器莫名重启了?-b -1看上一次生命周期的最后几十行,死因经常就在里面。

第 ② 层:按时间

journalctl--sincetoday# 今天以来journalctl--since"09:00"--until"09:30"# 今早 9 点到 9 点半journalctl--since"2026-10-10 09:00:00"# 精确时间点journalctl--since"-1h"# 最近 1 小时

第 ③ 层:按 Unit

journalctl-unginx# 单个服务journalctl-unginx-ussh# 多个服务一起看

第 ④ 层:按级别

日志共 8 个级别,排查故障从err往上找:

级别含义
0 emerg系统不可用
1 alert必须立即处理
2 crit严重
3 err错误(排障起点)
4 warning警告
5 notice正常但重要
6 info常规信息
7 debug调试
journalctl-perr# 只看 err 及以上journalctl-pwarning-unginx# nginx 的警告及以上

第 ⑤ 层:按字段(精确定位)

journalctl_PID=1000# 只看这个 PID 发出的journalctl_UID=1001# 只看这个用户的journalctl-g"timeout"# 全文搜索关键字(像 grep)

组合拳示例:今早 9 点 nginx 502,一条命令锁定现场:

journalctl-b--since"09:00"--until"09:15"-unginx-perr

这次开机 + 9:00-9:15 + nginx 服务 + err 级别——四层过滤叠加,几万行日志瞬间只剩肇事的那几条。

默认很多发行版 journal 存内存、重启即失;想持久化保存,建目录后重启:

sudomkdir-p/var/log/journalsudosystemctl restart systemd-journald

八、dmesg:内核在说什么

dmesg读的是内核环形缓冲区——开机自检、驱动加载、硬件报错、内核杀进程,全在这里。它和 journalctl 的分工:dmesg 只管内核层,journalctl 管应用层。

dmesg# 全量(时间戳是秒数,不友好)dmesg-T# 转成人类可读的时间(必加)dmesg-lerr,warn# 只看错误和警告dmesg-w# 持续盯着(像 tail -f)

三大经典场景:

① 进程被 OOM Killer 干掉了——服务莫名其妙消失,日志里还没有应用报错?查这个:

dmesg-T|grep-i"killed process"# Out of memory: Killed process 1234 (java) total-vm:...

内存不足时内核会挑"最肥"的进程杀掉保命——Java 应用是头号受害者。

② 磁盘要坏了:

dmesg-T|grep-iE"i/o error|bad sector"

③ 网卡/硬盘掉线重连:

dmesg-T|tail-50# 看最近的内核事件

内存口诀:进程离奇失踪查 dmesg 的 OOM,服务报错查 journalctl,文件日志查 /var/log。


九、系统时间、时区与 Chrony

9.1 先看清现状

date# 当前时间date+"%F %T"# 2026-10-10 09:00:01timedatectl# 时间、时区、NTP 同步状态一览

timedatectl输出重点看两行:

Time zone: Asia/Shanghai (CST, +0800) System clock synchronized: yes ← 时间已和 NTP 源同步 NTP service: active ← 时间同步服务在跑

9.2 时区设置

timedatectl list-timezones|grepShanghaisudotimedatectl set-timezone Asia/Shanghai

服务器建议一律用Asia/Shanghai;跨国的多机器环境甚至可以统一用 UTC 避免换算——关键不是用哪个,是全部机器保持一致,不然比对多机日志时差 8 小时,能把人逼疯。

9.3 为什么必须做时间同步

  • 日志取证:两台机器时间差 3 分钟,攻击链的先后顺序就对不上
  • 证书校验:HTTPS/TLS 证书有有效期,时间飘了直接握手失败
  • 分布式系统:数据库主从、Hadoop 集群对时间偏差极敏感,超限直接拒绝工作

时间不同步不是"表不准"的小事,是生产事故的隐形来源。

9.4 Chrony:现代时间同步方案

主流发行版已用 chrony 取代老的 ntpd:同步更快、断网恢复后修正更猛,还能间歇联网工作。

sudoaptinstallchrony# Ubuntu(Rocky 一般自带)systemctl status chronyd# Rocky 服务名叫 chronyd

配置公网时间源——编辑配置文件(Ubuntu 在/etc/chrony/chrony.conf,Rocky 在/etc/chrony.conf):

# 用 pool 指定时间服务器(可写多行做冗余) pool ntp.aliyun.com iburst pool time1.cloud.tencent.com iburst server ntp.tuna.tsinghua.edu.cn iburst # 允许本机时间慢慢校准(不猛跳) makestep 1.0 3

国内常用公网时间源:

提供方地址
阿里云ntp.aliyun.com
腾讯云time1.cloud.tencent.com
清华ntp.tuna.tsinghua.edu.cn
NTP Pool 中国区cn.pool.ntp.org

改完重启并验证:

sudosystemctl restart chrony# 看时间源状态(^* 开头的就是当前正在用的源)chronyc sources-v# ^* 203.107.6.88 2 10 377 133 -1234us[ -567us] +/- 12ms# 看同步详情chronyc tracking# 时间差太多?立刻硬校准(跳变对齐,不用慢慢磨)sudochronyc makestep

chronyc sources -v输出解读:行首^*表示已同步并选定使用的源,^+是备选,^?是还没连上的——全是^?说明同步有问题,查网络或防火墙(NTP 用 UDP 123 端口)。

最后回到timedatectl确认闭环:

timedatectl# System clock synchronized: yes ← 到这里,时间这条线就稳了

十、总结

这一期把"服务怎么被管起来"讲完了:

  1. systemd 是 PID 1,管理的基本单位是 unit(service/target/timer/socket…),开机自启和崩溃自愈都归它管。
  2. systemctl 五连(start/stop/restart/reload/status)+ 自启三连(enable/disable/is-enabled),改配置用 reload 不用 restart;enable --now一条顶两条。
  3. 改了 unit 文件必须daemon-reload,这是"配置不生效"的头号原因。
  4. 手写 service unit:[Unit] 讲关系、[Service] 讲怎么跑、[Install] 讲挂哪;Restart=on-failure实现崩溃自愈;部署完按Unit → 进程 → 端口 → 应用四层验证。
  5. 日志三入口:服务问题 journalctl、认证看 /var/log、内核硬件看 dmesg——进程离奇失踪先查 OOM。
  6. journalctl 五层缩小窗口:boot → 时间 → Unit → 级别 → 字段,多层条件叠加就是"数据库查询"。
  7. tail -F 优于 tail -f:日志轮转后不会跟丢。
  8. 时间同步用 Chrony:配国内源、chronyc sources -v看^*、makestep 硬校准;多机日志比对的前提是时间一致。

练习环境:Ubuntu 24.04 LTS / Rocky Linux 9 虚拟机

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询