systemd是现代Linux的初始化系统(init system),替代了传统的SysV init。它不仅管理服务启动,还提供日志、定时器、挂载、网络等统一管理。
| 特性 | SysV init | systemd |
|---|---|---|
| 启动方式 | 串行执行脚本 | 并行启动服务 |
| 依赖管理 | 手动LSB头 | 声明式依赖 |
| 服务监控 | 无 | 自动重启(cgroup) |
| 日志 | 分散在/var/log | journald统一 |
| 定时任务 | cron | Timer单元 |
| 套接字激活 | 无 | 支持 |
systemd ──┬── systemd-init # PID 1,init进程
├── systemctl # 服务管理命令
├── journalctl # 日志查询
├── systemd-analyze # 启动分析
├── logind # 登录管理
├── resolved # DNS解析
├── networkd # 网络管理
└── timesyncd # 时间同步
| 类型 | 后缀 | 功能 |
|---|---|---|
| Service | .service | 服务守护进程 |
| Target | .target | 运行级别/状态组 |
| Timer | .timer | 定时任务 |
| Socket | .socket | 套接字激活 |
| Mount | .mount | 文件系统挂载 |
| Path | .path | 路径监控 |
| Swap | .swap | Swap空间 |
| Slice | .slice | Cgroup资源控制组 |
/etc/systemd/system/ # 管理员自定义(最高优先级)
/run/systemd/system/ # 运行时动态生成
/usr/lib/systemd/system/ # 软件包安装的默认单元
$ ls /etc/systemd/system/ | head -15
basic.target.wants chronyd.service cloud-final.service.wants cloud-init.target.wants dbus-org.freedesktop.ModemManager1.service dbus-org.freedesktop.resolve1.service dbus-org.freedesktop.thermald.service dbus-org.freedesktop.timesync1.service display-manager.service.wants emergency.target.wants final.target.wants getty.target.wants graphical.target.wants hibernate.target.wants hybrid-sleep.target.wants
# 启动/停止/重启
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx # 重载配置(不中断服务)
# 开机自启
sudo systemctl enable nginx
sudo systemctl disable nginx
sudo systemctl enable --now nginx # 启用并立即启动
# 查看状态
systemctl status nginx
systemctl is-active nginx
systemctl is-enabled nginx
$ systemctl list-units --type=service --state=running | head -15
UNIT LOAD ACTIVE SUB DESCRIPTION chrony.service loaded active running chrony, an NTP client/server containerd.service loaded active running containerd container runtime cron.service loaded active running Regular background program processing daemon dbus.service loaded active running D-Bus System Message Bus docker.service loaded active running Docker Application Container Engine getty@tty1.service loaded active running Getty on tty1 ModemManager.service loaded active running Modem Manager multipathd.service loaded active running Device-Mapper Multipath Device Controller networkd-dispatcher.service loaded active running Dispatcher daemon for systemd-networkd nginx.service loaded active running A high performance web server and a reverse proxy server polkit.service loaded active running Authorization Manager rc-local.service loaded active running /etc/rc.local Compatibility rsyslog.service loaded active running System Logging Service serial-getty@ttyS0.service loaded active running Serial Getty on ttyS0
$ systemctl get-default
graphical.target
| Target | SysV级别 | 说明 |
|---|---|---|
| poweroff.target | 0 | 关机 |
| rescue.target | 1 | 救援模式 |
| multi-user.target | 3 | 多用户命令行 |
| graphical.target | 5 | 图形界面 |
| reboot.target | 6 | 重启 |
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application Service
After=network.target mysql.service
Wants=mysql.service
[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/start.sh
ExecStop=/opt/myapp/bin/stop.sh
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
| 类型 | 说明 |
|---|---|
| simple | 默认,主进程不fork |
| forking | 传统守护进程,fork后父进程退出 |
| oneshot | 一次性任务,配合RemainAfterExit=yes |
| notify | 进程通过sd_notify通知就绪 |
| idle | 等所有任务完成后再启动 |
| 指令 | 强依赖 | 说明 |
|---|---|---|
| Requires | 是 | 依赖必须成功 |
| Wants | 否 | 依赖最好成功 |
| After | N/A | 在依赖之后启动 |
| Before | N/A | 在依赖之前启动 |
| Conflicts | N/A | 互斥 |
| BindsTo | 是 | 依赖停则本单元也停 |
# 修改单元文件后必须重载
sudo systemctl daemon-reload
sudo systemctl restart myapp
$ journalctl -b -n 10 --no-pager
May 19 21:55:01 VM-4-3-ubuntu CRON[602221]: pam_unix(cron:session): session closed for user root May 19 21:55:01 VM-4-3-ubuntu CRON[602219]: pam_unix(cron:session): session closed for user root May 19 21:55:01 VM-4-3-ubuntu CRON[602220]: pam_unix(cron:session): session closed for user root May 19 21:55:13 VM-4-3-ubuntu node[544551]: 2026-05-19T21:55:13.722+08:00 [diagnostic] stalled session: sessionId=34fc3f41-76d1-453f-9eb4-c6b8785c14b5 sessionKey=agent:main:subagent:6830370a-aa0e-488e-a6f5-2b7f537e695d state=processing age=1482s queueDepth=0 reason=active_work_without_progress classification=stalled_agent_run activeWorkKind=model_call lastProgress=model_call:started lastProgressAge=325s recovery=none May 19 21:55:38 VM-4-3-ubuntu sshd[602480]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=195.161.114.163 user=root May 19 21:55:39 VM-4-3-ubuntu sshd[602480]: Failed password for root from 195.161.114.163 port 57856 ssh2 May 19 21:55:43 VM-4-3-ubuntu node[544551]: 2026-05-19T21:55:43.722+08:00 [diagnostic] stalled session: sessionId=34fc3f41-76d1-453f-9eb4-c6b8785c14b5 sessionKey=agent:main:subagent:6830370a-aa0e-488e-a6f5-2b7f537e695d state=processing age=1512s queueDepth=0 reason=active_work_without_progress classification=stalled_agent_run activeWorkKind=model_call lastProgress=model_call:started lastProgressAge=355s recovery=none May 19 21:56:01 VM-4-3-ubuntu CRON[602688]: pam_unix(cron:session): session opened for user root(uid=0) by root(uid=0) May 19 21:56:01 VM-4-3-ubuntu CRON[602689]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &') May 19 21:56:01 VM-4-3-ubuntu CRON[602688]: pam_unix(cron:session): session closed for user root
# 常用查询
journalctl -b # 本次启动日志
journalctl -b -1 # 上次启动日志
journalctl -u nginx # nginx服务日志
journalctl -u nginx --since today
journalctl -p err # 错误级别及以上
journalctl -f # 实时跟踪
journalctl --disk-usage # 日志磁盘占用
$ systemd-analyze
Startup finished in 3.087s (kernel) + 17.240s (userspace) = 20.327s graphical.target reached after 16.489s in userspace.
$ systemd-analyze blame | head -10
7.047s apt-daily-upgrade.service 3.554s rc-local.service 3.304s cloud-init-local.service 3.002s systemd-journal-flush.service 2.877s snapd.seeded.service 2.685s docker.service 2.664s snapd.service 2.357s apport.service 2.133s containerd.service 1.961s systemd-networkd-wait-online.service
按需启动服务:当有连接到达时才启动服务进程,节省资源。
# myapp.socket
[Unit]
Description=MyApp Socket
[Socket]
ListenStream=8080
[Install]
WantedBy=sockets.target
# myapp.timer
[Unit]
Description=Run MyApp daily
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
# 使用systemctl edit覆盖特定参数
sudo systemctl edit myapp
# 自动创建 /etc/systemd/system/myapp.service.d/override.conf
# [Service]
# LimitNOFILE=100000
# Environment=DEBUG=true
sudo systemctl daemon-reload
sudo systemctl restart myapp
systemctl status myapp -l
journalctl -u myapp -n 50 --no-pager
systemctl cat myapp
systemd-analyze verify /etc/systemd/system/myapp.servicesudo tee /opt/hello.sh <<'EOF'
#!/bin/bash
while true; do
echo "Tue May 19 09:56:13 PM CST 2026: Hello from myapp"
sleep 5
done
EOF
sudo chmod +x /opt/hello.sh
sudo tee /etc/systemd/system/hello.service <<'EOF'
[Unit]
Description=Hello World Service
After=network.target
[Service]
Type=simple
ExecStart=/opt/hello.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now hello
systemctl status hello
journalctl -u hello -n 10
# 清理
sudo systemctl disable --now hello
sudo rm /etc/systemd/system/hello.service /opt/hello.sh
sudo systemctl daemon-reload✅ 理解systemd架构与Unit类型
✅ 掌握systemctl服务管理
✅ 学会编写Service Unit文件
✅ 掌握journalctl日志查询
✅ 了解systemd-analyze性能分析