这个命令是干啥的
我刚入行那会儿,用的还是CentOS 6,管理服务全靠 service 和 chkconfig。那时候启动个nginx要敲 service nginx start,设置开机自启还得 chkconfig nginx on。后来换到CentOS 7,发现这些命令虽然还能用,但系统会提示你"推荐用systemctl"。现在主流发型版基本都切systemd了,Ubuntu 16.04+、CentOS 7+、Debian 8+、Fedora都是。
systemctl 是systemd的主管理工具。说白了,它就是管系统里那些"后台进程"(也就是服务)的。启动、停止、重启、看状态、设置开机自启,全用它。
基本用法(3分钟上手)
先来最常用的,查个服务状态:
# 查看nginx服务的运行状态
systemctl status nginx
输出大概长这样:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2026-06-22 08:30:00 CST; 1h ago
注意看几个关键字段:Loaded后面有没有enabled,表示开机自启有没有开;Active后面的active (running)才是真在跑。
常用命令就这几条:
# 启动服务
systemctl start nginx
# 停止服务
systemctl stop nginx
# 重启服务(先停再启)
systemctl restart nginx
# 重新加载配置(不中断服务,适合改配置后)
systemctl reload nginx
# 设置开机自启
systemctl enable nginx
# 关闭开机自启
systemctl disable nginx
# 查看所有正在运行的服务
systemctl list-units --type=service --state=running
# 查看所有服务,包括没启动的
systemctl list-units --type=service --all
有个参数我经常用:--failed,一键找出挂了哪些服务:
# 列出所有失败的服务
systemctl --failed
我巡检机器的时候,习惯先跑一下这个,比一个个查省事多了。
进阶骚操作
写自己的service单元文件
有时候我们自己编译安装的程序,也想像系统服务一样用systemctl管理。比如我自己编译了个nginx,想写个service文件。
路径在 /usr/lib/systemd/system/ 或者 /etc/systemd/system/(推荐放后者,优先级高)。
我写过一个简单的:
# 创建用户自定义的service文件,放在/etc目录下不会被系统更新覆盖
vim /etc/systemd/system/myapp.service
内容:
[Unit]
Description=我的自定义应用
After=network.target
[Service]
Type=simple
User=www
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/myapp --config /etc/myapp.conf
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
几个关键点:
- After=network.target:等网络好了再启动
- Restart=on-failure:挂了自己重启
- RestartSec=5:停5秒再重启,防止频繁刷日志
写完后重载配置:
# 重新加载所有service单元文件
systemctl daemon-reload
# 启动自定义服务
systemctl start myapp
# 设置开机自启
systemctl enable myapp
看依赖关系
服务之间有依赖,比如nginx依赖网络,mysql依赖磁盘挂载。可以用这个看:
# 查看nginx依赖了啥
systemctl list-dependencies nginx
反过来,想看哪些服务依赖某个target(相当于运行级别):
# 查看多用户模式依赖了哪些服务
systemctl list-dependencies multi-user.target
系统启动耗时分析
# 查看系统启动各阶段的耗时
systemd-analyze
# 查看每个服务的启动耗时
systemd-analyze blame
有次我发现服务器启动特别慢,一查 systemd-analyze blame,发现一个没用的服务占了30秒。直接disable掉,启动时间从2分钟降到20秒。
避坑指南
坑1:改了service文件没reload
我最开始犯过这个错:改了 /etc/systemd/system/xxx.service,然后直接 systemctl restart xxx。结果发现改的参数根本没生效。因为systemd缓存了配置。
正确做法:改完一定要先 systemctl daemon-reload,再restart。
坑2:enable了但机器重启没自动启动
这情况我踩过两次。排查方向:
1. 先看enable状态:systemctl is-enabled xxx,返回enabled才行
2. 看有没有依赖问题:systemctl list-dependencies xxx
3. 看启动日志:journalctl -u xxx,看看启动时出了啥错
4. 最坑的一种:服务启动得太早,依赖的网络或磁盘还没好,导致启动失败。这时要检查 After= 和 Wants= 配置对不对
坑3:Type配错
Type=simple 是默认的,意思是ExecStart指定的进程启动就算服务OK了。但有些程序会fork子进程(像传统的nginx),父进程启动完就退出。这时如果你用Type=simple,systemctl会以为服务挂了。
解决方案:如果是forking模式的服务,要写成 Type=forking,还要配 PIDFile= 指到pid文件位置。
坑4:kill模式导致数据丢失
默认情况下,systemctl stop是发SIGTERM,过一段时间没响应就SIGKILL。如果是数据库类服务,你这样粗暴杀可能丢数据。
我就在redis上吃过亏。解决方案是在service文件里加:
[Service]
TimeoutStopSec=30
KillMode=process
KillMode=process 只杀主进程,让子进程自己处理退出。当然这要看你具体服务支持不支持。
实战场景(重点!结合真实运维场景)
场景1:nginx挂了的自动恢复
有次公司线上nginx挂了,被报警系统发现才去重启,中间大概断了5分钟业务。后来我在service单元文件里加了自愈机制:
[Service]
Restart=always
RestartSec=3
StartLimitInterval=60
StartLimitBurst=3
意思是挂了就重启,但如果60秒内挂了3次以上,就不重启了(防止死循环)。配合monit或者supervisor,基本能做到秒级恢复。
场景2:批量巡检服务器
我写过一个脚本,批量连接几十台机器检查服务状态:
# 批量检查所有机器的nginx和mysql是否正常
for host in `cat server_list.txt`; do
echo "=== $host ==="
ssh $host "systemctl is-active nginx && echo 'nginx OK' || echo 'nginx 挂了'"
ssh $host "systemctl is-active mysql && echo 'mysql OK' || echo 'mysql 挂了'"
done
systemctl is-active返回0或非0,很适合脚本里判断。
场景3:排查业务响应慢
有次业务反馈响应慢,我先用systemctl排查是不是服务自动重启了:
# 查看最近5次服务重启记录
journalctl -u myapp --since "1 hour ago" | grep -i "start\|stop\|fail"
发现服务在半小时内自动重启了3次。进一步看日志才发现是OOM killer把进程杀了,systemd又自动拉起来,导致服务间歇性不可用。
后来优化了内存配置,同时加上了RestartSec的延时,给监控系统足够的时间报警而不是让进程频繁重启。
场景4:单独看某个服务的启动日志
journalctl是systemd的日志神器,配合systemctl很好用:
# 查看某个服务的启动日志
journalctl -u nginx
# 只看最近10分钟
journalctl -u nginx --since "10 min ago"
# 实时追踪日志
journalctl -u nginx -f
今日作业
写一个自定义systemd service文件,启动一个Python HTTP服务(假设你的Python脚本路径是 /opt/myserver/app.py,它监听8080端口,使用 python3 /opt/myserver/app.py 启动,工作目录为 /opt/myserver),要求:
1. 网络就绪后才启动
2. 挂了自动重启,等待5秒
3. 开机自启
4. 给出完整的service文件内容和启动命令
写完service文件后,列出你需要的完整操作步骤(从创建文件到服务正常运行的每一步命令)。