一文掌握 Linux systemd:基础运维和实战技巧

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 功能,更加灵活。👉 例如:每天凌晨备份数据库。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容