Linux服务的启动和管理,运维大佬基本上都会使用。说到服务管理,很多小伙伴第一反应就是systemctl start nginx,但其实背后的 systemd 远不止“启动服务”这么简单。今天就带大家从原理到实战,一步一步搞懂 systemd,并学会写一个自己的 systemd 服务单元。
一、systemd 的作用
Systemd的设计目标是,为系统的启动和管理提供一套完整的解决方案。
根据Linux 惯例,字母d是守护进程daemon的缩写。Systemd这个名字的含义,就是它要守护整个系统。
(Systemd 作者 Lennart Poettering)
使用了 Systemd,就不需要再用init了。Systemd 取代了initd,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。
它的主要作用有:
1. 系统初始化系统启动后,systemd 会负责启动内核之外的用户空间进程,例如挂载文件系统、启动网络服务等。
2. 服务管理systemd 提供统一的服务管理命令:启动、停止、重启、查看状态,甚至还能实现自动拉起和依赖控制。
3. 依赖关系管理通过 unit 配置,systemd 可以定义服务的依赖顺序,比如数据库必须在 Web 服务之前启动。
4. 统一日志管理systemd 自带 journalctl,让你快速查看服务日志,统一了日志收集方式。
一句话总结:👉 systemd 就是 Linux 世界的“管家”,负责照顾系统从开机到服务运行的一切。
二、systemd命令入门
日常运维中,常用的 systemctl 命令几乎就这一套:
| 功能 | 命令示例 |
| 启动服务 | systemctl start nginx |
| 停止服务 | systemctl stop nginx |
| 重启服务 | systemctl restart nginx |
| 查看服务状态 | systemctl status nginx |
| 设置开机自启 | systemctl enable nginx |
| 禁用开机自启 | systemctl disable nginx |
| 重新加载配置 | systemctl daemon-reload |
| 查看所有服务 | systemctl list-units --type=service |
管理unit复制
# 立即启动一个服务
$ sudo systemctl start apache.service
# 立即停止一个服务
$ sudo systemctl stop apache.service
# 重启一个服务
$ sudo systemctl restart apache.service
# 杀死一个服务的所有子进程
$ sudo systemctl kill apache.service
# 重新加载一个服务的配置文件
$ sudo systemctl reload apache.service
# 重载所有修改过的配置文件
$ sudo systemctl daemon-reload
# 显示某个 Unit 的所有底层参数
$ systemctl show httpd.service
# 显示某个 Unit 的指定属性的值
$ systemctl show -p CPUShares httpd.service
# 设置某个 Unit 的指定属性
$ sudo systemctl set-property httpd.service CPUShares=500
# 依赖关系
Unit 之间存在依赖关系:A 依赖于 B,就意味着 Systemd 在启动 A 的时候,同时会去启动 B。
systemctl list-dependencies命令列出一个 Unit 的所有依赖。
$ systemctl list-dependencies nginx.service1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.
- unit状态查看
复制
# 列出正在运行的 Unit
$ systemctl list-units
# 列出所有Unit,包括没有找到配置文件的或者启动失败的
$ systemctl list-units --all
# 列出所有没有运行的 Unit
$ systemctl list-units --all --state=inactive
# 列出所有加载失败的 Unit
$ systemctl list-units --failed
# 列出所有正在运行的、类型为 service 的 Unit
$ systemctl list-units --type=service
# 显示某个 Unit 是否正在运行
$ systemctl is-active application.service
# 显示某个 Unit 是否处于启动失败状态
$ systemctl is-failed application.service
# 显示某个 Unit 服务是否建立了启动链接
$ systemctl is-enabled application.service1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.
Systemd 的主命令,用于管理系统。复制
# 重启系统
$ sudo systemctl reboot
# 关闭系统,切断电源
$ sudo systemctl poweroff
# CPU停止工作
$ sudo systemctl halt
# 暂停系统
$ sudo systemctl suspend
# 让系统进入冬眠状态
$ sudo systemctl hibernate
# 让系统进入交互式休眠状态
$ sudo systemctl hybrid-sleep
# 启动进入救援状态(单用户状态)
$ sudo systemctl rescue
3.2 systemd-analyze
systemd-analyze命令用于查看启动耗时。1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.
systemd-analyze 查看启动耗时复制
$ systemd-analyze
# 查看每个服务的启动耗时
$ systemd-analyze blame
# 显示瀑布状的启动过程流
$ systemd-analyze critical-chain
# 显示指定服务的启动流
$ systemd-analyze critical-chain atd.service1.2.3.4.5.6.7.8.9.10.
而日志查询则用:日志查询
systemd管理的服务可以统一使用journalctl实现日志查看复制
# 查看所有日志(默认情况下 ,只保存本次启动的日志)
$ sudo journalctl
# 查看内核日志(不显示应用日志)
$ sudo journalctl -k
# 查看系统本次启动的日志
$ sudo journalctl -b
$ sudo journalctl -b -0
# 查看上一次启动的日志(需更改设置)
$ sudo journalctl -b -1
# 查看指定时间的日志
$ sudo journalctl --since="2012-10-30 18:17:16"
$ sudo journalctl --since "20 min ago"
$ sudo journalctl --since yesterday
$ sudo journalctl --since "2015-01-10" --until "2015-01-11 03:00"
$ sudo journalctl --since 09:00 --until "1 hour ago"
# 显示尾部的最新10行日志
$ sudo journalctl -n
# 显示尾部指定行数的日志
$ sudo journalctl -n 20
# 实时滚动显示最新日志
$ sudo journalctl -f
# 查看指定服务的日志
$ sudo journalctl /usr/lib/systemd/systemd
# 查看指定进程的日志
$ sudo journalctl _PID=1
# 查看某个 Unit 的日志
$ sudo journalctl -u nginx.service
$ sudo journalctl -u nginx.service --since today
# 实时滚动显示某个 Unit 的最新日志
$ sudo journalctl -u nginx.service -f
# 合并显示多个 Unit 的日志
$ journalctl -u nginx.service -u php-fpm.service --since today
# 查看指定优先级(及其以上级别)的日志,共有8级
# 0: emerg
# 1: alert
# 2: crit
# 3: err
# 4: warning
# 5: notice
# 6: info
# 7: debug
$ sudo journalctl -p err -b
# 日志默认分页输出,--no-pager 改为正常的标准输出
$ sudo journalctl --no-pager
# 以 JSON 格式(单行)输出
$ sudo journalctl -b -u nginx.service -o json
# 以 JSON 格式(多行)输出,可读性更好
$ sudo journalctl -b -u nginx.service -o json-pretty
# 显示日志占据的硬盘空间
$ sudo journalctl --disk-usage
# 指定日志文件占据的最大空间
$ sudo journalctl --vacuum-size=1G
# 指定日志文件保存多久
$ sudo journalctl --vacuum-time=1years1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.
三、认识Systemd 配置:自己写一个 systemd 服务
Systemd 默认从目录/etc/systemd/system/读取配置文件。里面存放的大部分文件都是符号链接,指向目录/usr/lib/systemd/system/,真正的配置文件存放在这个目录。复制
systemctl list-unit-files命令用于列出所有配置文件。
# 列出所有配置文件
$ systemctl list-unit-files
# 列出指定类型的配置文件
$ systemctl list-unit-files --type=service1.2.3.4.5.
假设我们有一个简单的 Python 脚本复制
#!/usr/bin/env python3
import time
while True:
with open("/tmp/demo_app.log", "a") as f:
f.write("App is running...\n")
time.sleep(5)1.2.3.4.5.6.
1. 写一个 systemd unit 文件
新建文件 /etc/systemd/system/demo_app.service复制
[Unit]
Description=My Demo App
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/demo_app/app.py
Restart=always
RestartSec=3
User=nobody
[Install]
WantedBy=multi-user.target1.2.3.4.5.6.7.8.9.10.11.12.13.
2. 加载并启动服务
复制
systemctl daemon-reload
systemctl start demo_app
systemctl enable demo_app1.2.3.
3. 验证
复制
systemctl status demo_app
tail -f /tmp/demo_app.log1.2.
这样我们就写了一个最简单的自定义服务。
四、systemd 的不同使用类型场景
systemd 的 Service 里有多种 Type 类型,适合不同应用场景:
1. Type=simple默认类型,适合常驻前台的应用。👉 如:Nginx、Node.js 服务。
2. Type=forking服务会自己 fork 到后台运行,systemd 需要跟踪子进程。👉 如:MySQL、Tomcat。
3. Type=oneshot只运行一次就退出,适合执行初始化脚本。👉 如:启动时挂载磁盘脚本。
4. 定时任务(Timer Unit)systemd 自带定时器,可以替代部分 cron 功能,更加灵活。👉 例如:每天凌晨备份数据库。



暂无评论内容