← 回目录
14 Week 03 · 服务和进程 · 实战

实战:自己搞坏 nginx,再修好

这是整个三十天里最有价值的一天。把服务弄坏,再靠日志把它救回来——这个循环走通一次,你就真的会排障了。

前面十三天学的是工具,今天是把工具连成流程。排障能力不是读出来的,是修出来的

开始前先备份

Day 02 的规矩,今天正式用上:

sudo cp -a /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%F)

有了这个,今天你可以放心大胆地搞破坏。

标准排障流程

今天要练成条件反射的东西
服务起不来,按这个顺序走
1 · systemctl status
Active 是什么状态,顺便读最后那几行日志——原因经常直接就在那。
2 · journalctl -xe
看详细报错。这一步能定位到具体是哪类问题。
3 · 配置语法检查
nginx 用 nginx -t,sshd 用 sshd -t它会告诉你第几行错。
4 · 端口占用
ss -tunlp | grep 端口号——是不是别的进程先占了。
5 · 权限 / SELinux
前面都对还起不来,查这个。第 19 天详讲。

故障一:配置语法错

最常见的一种
① 制造故障
$ sudo vi /etc/nginx/nginx.conf

# 找到任意一行结尾的分号,把它删掉
# 比如把    listen       80;
#     改成    listen       80
# 然后 Esc → :wq 保存
② 重启,它会失败
$ sudo systemctl restart nginx
Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xe" for details.
③ 别急着改回去,按流程查
$ systemctl status nginx
     Active: failed (Result: exit-code) since ...
     Process: 4102 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=1)
     ↑ 已经能看出是配置检查那一步挂的

$ sudo journalctl -xe | tail -20
nginx: [emerg] directive "listen" is not terminated by ";" in
       /etc/nginx/nginx.conf:47
     ↑ 报错说得很清楚:第 47 行,缺分号

$ sudo nginx -t
nginx: [emerg] directive "listen" is not terminated by ";" in /etc/nginx/nginx.conf:47
nginx: configuration file /etc/nginx/nginx.conf test failed
④ 修复
$ sudo vi /etc/nginx/nginx.conf
   :47      ← Day 04 学的,直接跳到第 47 行
   i 加回分号 → Esc → :wq

$ sudo nginx -t                 ← 改完先检查,别直接重启
nginx: configuration file /etc/nginx/nginx.conf test is successful

$ sudo systemctl restart nginx
$ systemctl status nginx        ← 确认 active (running)
养成这个习惯

改完配置,先 nginx -t 检查,再 systemctl reload

生产环境上如果直接 restart,配置有错就是一次真实的服务中断;先 -t 检查的话,错了也只是你自己看到一行报错,服务还好好跑着。

这个习惯本身就是一个能在面试里讲的点。

故障二:端口被占

第二常见
① 制造故障
$ sudo systemctl stop nginx

# 用别的东西把 80 端口占住
$ sudo python3 -m http.server 80 &

$ sudo systemctl start nginx
Job for nginx.service failed ...
② 排查
$ sudo journalctl -xe | tail -10
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
     ↑ 端口被占用,说得明明白白

$ sudo ss -tunlp | grep :80
tcp  LISTEN  0  5  0.0.0.0:80  0.0.0.0:*  users:(("python3",pid=4321,fd=3))
     ↑ 找到是谁占的:python3,PID 4321
③ 修复
$ sudo kill 4321               # Day 11 学的,先温和地停
$ sudo ss -tunlp | grep :80    # 确认端口空出来了
$ sudo systemctl start nginx
$ systemctl status nginx
生产环境不能直接杀

真实环境里发现端口被占,第一反应不该是杀掉对方——先搞清楚那是什么服务、是不是更重要。

要么改自己服务的端口,要么跟对方的负责人确认后再动。这个判断力比命令更重要。

故障三:文件权限

把第二周的知识接上
① 制造故障
$ sudo chmod 000 /usr/share/nginx/html/index.html
$ curl -I http://127.0.0.1
HTTP/1.1 403 Forbidden
② 按 Day 07 的三层顺序排查
# 第一层:nginx 以谁的身份跑
$ ps aux | grep "nginx: worker" | head -1
nginx  4501  ... nginx: worker process

# 第二层:文件权限和属主
$ ls -l /usr/share/nginx/html/index.html
----------. 1 root root 612 ... index.html
   ↑ 000,谁都读不了 —— 原因找到

# 看 nginx 自己的错误日志,会说得更直白
$ sudo tail -3 /var/log/nginx/error.log
[error] open() "/usr/share/nginx/html/index.html" failed (13: Permission denied)
③ 修复
$ sudo chmod 644 /usr/share/nginx/html/index.html
$ curl -I http://127.0.0.1
HTTP/1.1 200 OK
注意这次不用重启服务

权限问题改完立刻生效,nginx 不需要 reload——因为它是每次请求时才去读文件的。

分清「改配置要重载」和「改数据不用重载」,能省下不必要的服务中断。

把今天串成一个面试故事

这才是今天真正的产出
「讲一次你排查故障的经历」

「有次改完 nginx 配置重启,服务起不来。我先看 systemctl status,显示 failed 在配置检查那一步;再 journalctl -xe,报错直接给出了文件名和行号——第 47 行少个分号。用 vi:47 跳过去补上,nginx -t 检查通过后再 reload。」

后来我养成了习惯:改完配置一定先 nginx -t 再重载,避免线上直接挂掉。」

有现象、有排查步骤、有工具、有结果,最后还有一个改进的习惯——这就是一个完整的故事。

今天的实战

三个故障全做一遍 · 约 30 分钟

今天时间会比平时长,但值得。请务必自己动手,不要只读。

  • 先备份sudo cp -a /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%F)
  • 故障一:删掉一个分号 → 重启失败 → 不看本页,自己按 status → journalctl -xe → nginx -t 的顺序找出行号 → 修复 → 验证
  • 故障二:用 sudo python3 -m http.server 80 & 占住端口 → 启动 nginx 失败 → 用 ss -tunlp 找出占用者 → 处理 → 验证
  • 故障三chmod 000 首页 → curl -I 看到 403 → 按三层顺序排查 → 修复 → 再 curl 确认 200
  • 最后:把整个过程用自己的话讲一遍(说出声),就当面试在问你
如果哪一步卡住了

卡住是好事,说明找到了你的薄弱点。先别翻答案——回到对应那天的页面重看一遍(Day 12 systemctl / Day 13 journalctl / Day 07 属主权限),再回来试。

实在不行,你还有备份:sudo cp -a /etc/nginx/nginx.conf.bak.* /etc/nginx/nginx.conf

明天预告

Day 15 是机动日,不学新东西——凭记忆默写前三周的命令,找出自己的漏洞。

到明天为止,你就走完一半了。