这里写目录标题一、systemd 是什么解决什么问题二、配置文件在哪三、unit 文件结构三段拆解四、常用操作三个最容易混的动作改配置怎么生效命令速查日志journalctl一、systemd 是什么解决什么问题systemd是 Linux 的系统初始化和服务管理器PID 1开机后负责把整个系统拉起来、管理所有后台服务。systemctl是它的命令行客户端你敲systemctl xxx就是在跟 systemd 对话。它解决的核心问题让一个普通进程能像服务一样长期稳定运行。裸跑一个前台命令比如uvicorn app.main:app有三个致命问题systemd 全给它兜住裸跑的问题systemd 怎么解决关掉终端 / SSH 断了进程就死systemd 接管进程脱离终端跟会话无关进程崩了没人管得手动重启Restarton-failure/always崩了自动拉起开机不会自动起得人上去敲命令enable后开机自启日志散落在终端 / nohup.out日志统一进journalctl可按服务/时间筛选一句话systemd 把一个普通进程包装成服务给它生命周期管理、自愈、开机自启、统一日志。二、配置文件在哪systemd 的 service 配置叫unit 文件后缀.service。三个标准位置路径谁放的能不能改用途/lib/systemd/system/或/usr/lib/systemd/system/软件包安装自带不要改升级会覆盖系统自带服务nginx.service、docker.service/etc/systemd/system/管理员手动放的✅ 自己加你写的业务服务放这里~/.config/systemd/user/用户级不需要 sudo单独体系一般不用自己写的业务服务一律放/etc/systemd/system/。系统自带的服务如 nginx、docker不在这但你一样用systemctl管它们。三、unit 文件结构一份标准的 service unit 文件分三段[Unit]Description服务描述人看的status 里显示Afternetwork.target# 启动顺序网络就绪后再起不是硬依赖[Service]Typesimple# 主进程就是 ExecStart 启动的那个它死服务挂Userubuntu# 以谁的身份跑不用 rootGroupubuntuWorkingDirectory/path/to/app# 工作目录必填否则相对路径全找不到EnvironmentFile/path/to/.env# 从 .env 读环境变量必须 LF 换行ExecStart/path/to/.venv/bin/uvicorn app.main:app--host127.0.0.1--port8000# 启动命令可执行文件用绝对路径Restarton-failure# 非 0 退出码才重启要无条件拉起用 alwaysRestartSec5# 崩后等 5 秒再拉避免疯狂重启StandardOutputjournal# 日志输出到 journalctl不写默认也是 journalStandardErrorjournal[Install]WantedBymulti-user.target# 开机自启挂钩enable 时生效固定写法三段拆解[Unit]段 —— 元信息和启动顺序Description人看的描述systemctl status显示。After启动顺序不是依赖。“这些 target 起来之后再起我”但不会因为它们没起就失败。要硬依赖用Requires/Wants但一般After够用。[Service]段 —— 怎么跑这个进程核心Typesimple最常见。systemd 认为ExecStart启动的那个进程就是主进程主进程死了 systemd 认为服务挂了触发Restart。User/Group以谁的身份跑不要用 root。WorkingDirectory必填。不设当前目录是/代码里所有相对路径.env、模板、alembic.ini、静态文件全找不到。EnvironmentFile从文件读环境变量。必须 LF 换行CRLF 会让 systemd 解析失败。ExecStart启动命令。关键可执行文件用绝对路径因为 systemd 不加载 shell 的 PATH写uvicorn会找不到要写.venv/bin/uvicorn全路径。RestartRestartSec进程崩了等几秒自动拉起。on-failure非 0 退出才拉/always无条件拉连正常退出也拉/on-abnormal异常信号才拉。生产服务一般on-failure或always。StandardOutput/Errorjournal日志进 journalctl不写默认也是。[Install]段 —— 开机自启WantedBymulti-user.targetenable时把软连接建到multi-user.target.wants/下开机进多用户模式自动起。固定写法照抄。四、常用操作三个最容易混的动作新手最常搞混这三个命令它们分工明确命令干什么什么时候用systemctl daemon-reload让 systemd重新读 unit 文件改了.service文件后必跑systemctl enable xxx设开机自启建软连接想让开机自动起systemctl start xxx现在就启动进程现在就要跑起来记忆口诀daemon-reload管配置、enable管开机、start管当下。新建一个服务的标准三连sudosystemctl daemon-reload# 1. 读新写的 service 文件sudosystemctlenable--nowxxx# 2. 开机自启 立即启动enable 和 start 合一sudosystemctl status xxx# 3. 看状态确认改配置怎么生效两种配置别搞混改了什么要做什么改了.serviceunit 文件ExecStart、Restart 等daemon-reload然后restart两个都要daemon-reload 让 systemd 知道新配置restart 让进程用新配置重启只改了代码 /.env只restartunit 文件没动不用 daemon-reload命令速查# 服务管理sudosystemctl start xxx# 启动sudosystemctl stop xxx# 停止sudosystemctl restart xxx# 重启先停再起瞬断sudosystemctl reload xxx# 平滑重载仅当服务自己支持 reload 信号如 nginxsudosystemctl status xxx# 综合状态 最近日志sudosystemctl is-active xxx# 是否在跑active/inactivesudosystemctl is-enabled xxx# 是否开机自启enabled/disabledsudosystemctl is-failed xxx# 是否失败一启动就崩显示 failedsudosystemctlenablexxx# 设开机自启不启动sudosystemctl disable xxx# 取消开机自启日志journalctl所有服务日志统一收口到 journalctl不再满地找 nohup.outsudojournalctl-uxxx --no-pager-n50# 最近 50 行最常用sudojournalctl-uxxx-f# 实时跟踪类似 tail -fCtrlC 退出sudojournalctl-uxxx--sincetoday# 看今天的sudojournalctl-uxxx--since1 hour ago# 最近 1 小时sudojournalctl-uxxx-perr# 只看错误级别以上sudojournalctl-uxxx--since10:00--until12:00# 某时间段排错第一手journalctl -u 服务名 --no-pager -n 50看启动时报了什么。