目录一、引言systemd为何而生二、Unitsystemd的管理单元2.1 什么是Unit2.2 最常见的五类Unit2.3 Unit文件存放位置三、systemctl服务管理全操作3.1 服务状态与启停3.2 开启、禁用、屏蔽3.3 查看系统概况3.4 日志查看四、编写自定义.service文件4.1 三个关键section4.2 实战托管一个Python Web应用4.3 其他常用配置项4.4 Type选择指南4.5 使用override覆盖系统Unit五、综合实战将脚本变成稳定服务六、本篇小结动手练习七、下篇预告一、引言systemd为何而生在systemd出现之前Linux使用System V init又称SysV init管理服务。它的工作方式是系统启动时逐个执行/etc/rc.d/init.d/下的Shell脚本每个脚本按顺序排队前一个启动完才轮到下一个。这套机制在早期运行良好但随着系统日益复杂几个缺陷逐渐显现启动慢串行启动服务再多也只能一个一个来。系统全部就绪可能要几分钟管理弱无法精确描述服务间的依赖关系难以在某个服务崩溃后自动拉起监控差脚本成功启动后即退出无法跟踪进程的运行状态systemd正是为解决这些问题而生。它采用并行启动、依赖管理、进程监控三位一体的架构让服务管理从“看运气”变成了“可预期”。如今几乎所有主流Linux发行版RHEL/CentOS 7、Ubuntu 15.04、Debian 8都默认使用systemd。二、Unitsystemd的管理单元2.1 什么是Unit在systemd的世界里一切被管理的东西都叫Unit。一个Unit可以是一个后台服务如Nginx、MySQL一个启动目标如multi-user.target一个定时任务如每天3点执行备份一个Socker端口用于按需启动服务一个挂载点管理文件系统挂载每种Unit通过文件后缀名来区分类型。2.2 最常见的五类Unit后缀名称作用举例.service服务单元定义如何启动、停止、重启一个后台服务nginx.service.target目标单元将多个Unit编组实现运行级别的概念multi-user.target.socket套接字单元监听网络端口需要时才启动服务sshd.socket.timer定时器单元替代传统cron按时间触发任务logrotate.timer.mount挂载单元管理文件系统挂载点home.mount对运维来说.service服务单元接触最多是本文的重点.timer定时器是cron的替代方案在第16篇会详细介绍。2.3 Unit文件存放位置Unit文件分布在两类目录中优先级不同目录用途优先级/lib/systemd/system/系统预装的Unit文件包管理器安装的低/etc/systemd/system/管理员自定义的Unit文件高重要原则永远不要在/lib/systemd/system/中直接修改系统预装的Unit文件因为软件包更新会覆盖你的修改。需要自定义时应将文件复制到/etc/systemd/system/后再修改或使用systemctl edit创建覆盖文件。三、systemctl服务管理全操作systemctl是与systemd交互的核心命令所有Unit的生命周期管理都通过它完成。3.1 服务状态与启停查看状态是最常用的操作它展示的信息量远超一句“running”bashsystemctl status sshd输出会显示服务名称、描述、加载状态、活跃状态、进程PID、最近几行日志片段。出现故障时这里的信息是排查的第一手资料。启动、停止、重启bashsudo systemctl start nginx # 启动 sudo systemctl stop nginx # 停止 sudo systemctl restart nginx # 重启先stop再start sudo systemctl reload nginx # 重新加载配置不中断服务需要服务支持restart与reload的核心区别restart彻底关闭进程再启动。会中断服务但确保配置全部生效reload只让服务重读配置文件不中断进程。平滑变更但并非所有服务都支持HUP信号最佳实践修改配置后优先尝试reload如果服务不支持reload或修改涉及核心参数再用restart。3.2 开启、禁用、屏蔽Linux中“开机自启”和“当前运行”是两个独立的维度。以下命令决定了服务在启动时的行为bashsudo systemctl enable nginx # 设为开机自启 sudo systemctl disable nginx # 取消开机自启 sudo systemctl is-enabled nginx # 查看是否已设为开机自启enable做了什么它在/etc/systemd/system/对应target的目录下创建了一个软链接指向服务的Unit文件。执行disable就是删除这个软链接。mask屏蔽更彻底——它创建指向/dev/null的软链接使服务无论如何都无法被启动bashsudo systemctl mask some-service sudo systemctl unmask some-service3.3 查看系统概况systemd提供了强大的全局查看能力帮助快速了解系统状态bash# 查看所有活跃Unit systemctl list-units # 仅查看service类型的Unit最常用 systemctl list-units --typeservice # 查看所有Unit包括未激活的 systemctl list-units --all # 查看开机自启失败的Unit排错利器 systemctl list-units --failed # 查看Unit之间的依赖关系 systemctl list-dependencies nginx.service3.4 日志查看systemd自带日志组件journald它从内核启动的那一刻就开始记录无需等到syslog服务准备好bash# 查看某服务的全部日志 journalctl -u nginx # 查看本次启动以来的日志 journalctl -b # 查看上一次启动的日志排查“重启后服务就挂了”的神器 journalctl -b -1 # 实时跟踪类似tail -f journalctl -f # 按时间过滤 journalctl --since 2026-04-24 10:00:00 --until 2026-04-24 11:00:00 # 查看内核日志 journalctl -k四、编写自定义.service文件这是本文的实操重点——将你自己的应用程序托管给systemd。4.1 三个关键section一个.service文件由三个section组成[Unit]服务描述与依赖关系[Service]如何启动、停止该服务[Install]定义该服务如何成为开机自启的一部分4.2 实战托管一个Python Web应用假设你有一个Python脚本/opt/myapp/server.py需要作为后台服务长驻运行。我们一步步将它变成systemd托管的服务。第一步确保你的脚本可独立运行bashchmod x /opt/myapp/server.py # 在脚本第一行添加 #!/usr/bin/env python3如果还没有直接运行一次确认不会报错CtrlC停止即可。第二步创建.service文件bashsudo vim /etc/systemd/system/myapp.service填入以下内容ini[Unit] DescriptionMyApp Web Server Afternetwork.target [Service] Typesimple Usernobody Groupnogroup WorkingDirectory/opt/myapp ExecStart/usr/bin/python3 /opt/myapp/server.py Restarton-failure RestartSec5s [Install] WantedBymulti-user.target字段逐一解读Afternetwork.target确保在网络初始化完成后才启动避免“连不上数据库”Typesimple最简单的类型systemd认为ExecStart启动后服务即就绪User/Group服务以哪个用户身份运行。绝不要用root运行自定义服务这违反最小权限原则。可以创建专有系统用户运行WorkingDirectory工作目录ExecStart启动命令。必须使用绝对路径Restarton-failure进程异常退出时自动重启守护进程的关键保障RestartSec5s重启间隔5秒避免疯狂重启消耗资源WantedBymulti-user.target指定安装目标决定开机自启的时机第三步加载并启动bashsudo systemctl daemon-reload # 让systemd重读所有Unit文件 sudo systemctl start myapp # 启动服务 sudo systemctl status myapp # 确认运行正常确认正常后设为开机自启bashsudo systemctl enable myapp4.3 其他常用配置项ini# 服务类型按需选择 Typesimple # 默认主进程就是服务进程 Typeforking # 传统守护进程启动后fork到后台 Typeoneshot # 短暂任务执行一次后退出 # 环境变量 EnvironmentPORT8080 EnvironmentFile/etc/myapp/env.conf # 标准输出/错误重定向 StandardOutputappend:/var/log/myapp.log StandardErrorappend:/var/log/myapp.log # 启动前检查文件是否存在 ConditionPathExists/etc/myapp/config.yaml # 重启策略 Restartalways # 不管退出原因总重启 Restarton-failure # 仅异常退出时重启推荐 Restartno # 不自动重启4.4 Type选择指南Type的值直接决定了systemd如何判断服务“启动成功”选错可能导致服务启动失败或状态异常Type适用场景systemd的判定标准simple前台运行的程序如Python脚本ExecStart启动后立即认为readyforking传统守护进程如Nginx在旧版本中的模式父进程退出后认为readyoneshot一次性任务的脚本进程执行完毕退出后认为readynotify支持sd_notify的现代程序程序显式发送通知后认为ready新手建议如果你自己写的程序是“启动后一直在前台运行”的模式就用Typesimple。Nginx、MySQL等系统软件使用Typeforking它们在deb/rpm包自带的Unit文件中已经配好一般不需要你干预。4.5 使用override覆盖系统Unit如果你只需要微调已有Unit的某个选项如给Nginx加一个环境变量不需要复制整个文件bashsudo systemctl edit nginx.service系统会打开一个空的override文件保存到/etc/systemd/system/nginx.service.d/override.conf你只需填写要覆盖的内容ini[Service] EnvironmentEXTRA_OPTION1编辑完保存退出后执行sudo systemctl daemon-reload sudo systemctl restart nginx即可生效。这种方法不会污染系统原始文件也避免了软件包更新时的冲突。五、综合实战将脚本变成稳定服务假设你要部署一个监控脚本/opt/monitor/check.sh它每隔一段执行一次检查。你希望它在后台默默运行崩溃了能自动恢复开机自动启动完整操作流程bash# 1. 确保脚本可执行 chmod x /opt/monitor/check.sh # 2. 创建专有系统用户安全最佳实践 sudo useradd -r -s /bin/false monitor # -r创建系统账户 # -s /bin/false禁止该用户登录Shell # 3. 编写.service文件 sudo cat /etc/systemd/system/monitor.service EOF [Unit] DescriptionSystem Monitor Service Afternetwork.target [Service] Typesimple Usermonitor WorkingDirectory/opt/monitor ExecStart/bin/bash /opt/monitor/check.sh Restarton-failure RestartSec10s [Install] WantedBymulti-user.target EOF # 4. 重载配置并启动 sudo systemctl daemon-reload sudo systemctl start monitor # 5. 验证运行状态看到 active (running) 即为成功 sudo systemctl status monitor # 6. 查看实时日志确认脚本运行正常 sudo journalctl -u monitor -f # 7. 设开机自启再次验证 sudo systemctl enable monitor sudo systemctl is-enabled monitor六、本篇小结本篇掌握了systemd服务管理的完整技能核心概念Unit是systemd的管理单元.service是其中与运维关系最紧密的类型系统Unit在/lib/systemd/system/自定义Unit在/etc/systemd/system/systemctl速查命令功能start/stop启动/停止服务restart/reload重启服务 / 重载配置平滑enable/disable设/取消开机自启status查看状态最近日志list-units --failed列出失败单元daemon-reload重读所有Unit文件编写.service文件三个section[Unit]描述依赖[Service]定义启动[Install]指定自启ExecStart必须用绝对路径Restarton-failureRestartSec5s是守护进程标配服务强烈建议以非root用户运行用useradd -r创建系统账户动手练习bash# 1. 查看当前所有失败的Unit systemctl list-units --failed # 2. 查看Nginx或SSH服务的完整状态 systemctl status sshd # 3. 查看SSH服务的Unit文件内容 systemctl cat sshd # 4. 创建一个最简服务sleep 3600 sudo systemd-run --unittest-service \ --descriptionTest Service \ sleep 3600 # 用systemctl status test-service观察 # 用sudo systemctl stop test-service终止 # 5. 查看本次启动的所有日志中关于error的内容 journalctl -b | grep -i error | head -20七、下篇预告有了systemd管理常驻服务你还需要另一种机制来管理临时性任务——比如“每天凌晨3点备份数据库”、“每周一清理临时文件”。下一篇我们将进入计划任务的世界学习Linux的两套任务调度框架crontab经典的定时任务系统分时日月周的灵活编排systemd timercron的现代替代品与systemd深度集成你将学会如何让机器在半夜自动替你干活以及日志轮替logrotate机制——它是如何防止日志文件撑爆磁盘的。延伸思考执行systemctl list-dependencies multi-user.target看看这个target包含了哪些服务。你可能会发现很多不知道的服务在后台运行。不用紧张——大多数是系统正常运行所必需的。逐步熟悉它们是加深对系统理解的好方法。