玩转Nginx 09 — 运维排障:三场"火灾"实战演练

玩转Nginx 09 --- 运维排障:三场"火灾"实战演练

一、本课目标(最后一课)

前 8 课学会了"怎么建",本课教你"坏了怎么修"。人为制造三场最常见的生产事故(火灾),用同一套排障四步法亲手扑灭,把"会看日志、会找证据"练成肌肉记忆。


二、排障四步法(本课主心骨)

① 看证据 → ② 查现场 → ③ 看日志 → ④ 定位修复

遇到任何异常,永远先问"证据是什么",不要瞎猜、不要乱改配置。


三、火灾 1:语法错误(缺分号)--- 配置文件写错了

完整命令流程

bash 复制代码
# ── 注入(制造事故):写 site3 配置时漏掉分号 ──
# 错误写法:server 127.0.0.1:8090      ← 漏了结尾的 ;
# 正确写法:server 127.0.0.1:8090;     ← 每个指令必须以 ; 收尾

# ── ① 看证据:reload 被拒 / 站点异常 ──
# curl 显示 502 Bad Gateway(upstream 配置语法错误导致整块 server 失效)

# ── ③ 看日志 / ② 查现场 ──
sudo nginx -t
# 输出:nginx: [emerg] directive "server" is not terminated by ";" in
#       /etc/nginx/sites-available/site3:XX(红字指明文件+行号)
cat /etc/nginx/sites-available/site3   # 打开配置肉眼找漏分号

# ── ④ 修复:补上分号 → 体检 → 重载 ──
sudo tee /etc/nginx/sites-available/site3 > /dev/null << 'EOF'
...(完整正确配置,upstream 里 server 127.0.0.1:8090; 带分号)...
EOF
sudo nginx -t && sudo systemctl reload nginx

# ── 验证:负载均衡轮询恢复 ──
curl -s http://127.0.0.1:8082/
# 输出交替出现 backend 与 backend-B,恢复正常
四步 操作 现象
注入 site3 配置里 server 127.0.0.1:8090 漏写 ; reload 后站点 502
① 看证据 nginx -t missing ";" / not terminated by ";",红字报错并指明文件+行号
② 查现场 cat 配置 一眼看出漏分号
④ 修复 补上 ;nginx -t → reload 负载均衡轮询恢复正常

核心认知:nginx -t 是配置的"体检",语法错会直接红字报行号,不合格绝不放行(reload 会被拒绝)。


四、火灾 2:端口冲突 --- "门牌号"被人占了

完整命令流程

bash 复制代码
# ── 注入(制造事故):在 site1 目录里起一个野 python 服务占住 8085 ──
nohup python3 -m http.server 8085 --bind 0.0.0.0 > /tmp/port8085.log 2>&1 &
# 注意:它从"当前启动目录"发文件,所以 ~/桌面/work/Nginx-lab/site1 下的
# 草稿页"我的第一个站点"被它拿走了

# ── ① 看证据:配好 site5(listen 8085)后 reload"静默失败"、curl 页面不对 ──
curl -s http://127.0.0.1:8085/
# 输出是"我的第一个站点"草稿页(python 的),不是 nginx 的站点

# ── ③ 看日志:bind 失败铁证 ──
sudo tail /var/log/nginx/error.log
# [emerg] bind() to 0.0.0.0:8085 failed (98: Unknown error)
# [emerg] still could not bind()

# ── ② 查现场:端口主人现形 ──
ss -tlnp | grep 8085
# LISTEN 0 511 0.0.0.0:8085 ... users:(("python3",pid=4060819,...))

# ── ④ 修复:杀占位者 → reload → 复验(一条组合拳) ──
kill 4060819 && sleep 1 && sudo systemctl reload nginx && ss -tlnp | grep 8085 && curl -s http://127.0.0.1:8085/ | head -3

# ── 验证:验明正身,确认是 nginx 的站点在营业 ──
curl -s http://127.0.0.1:8085/ | grep -i title
# 输出:<title>我的实战综合站</title>  ← 8085 改朝换代成功
四步 操作 现象
注入 野 python 服务(http.server 8085)占住 8085 nginx 配好 site5 却接不上
① 看证据 curl http://127.0.0.1:8085/ 页面返回"我的第一个站点"(python 从启动目录发的),不是 nginx 的站点
③ 看日志 tail /var/log/nginx/error.log bind() to 0.0.0.0:8085 failed (98) + still could not bind()
② 查现场 `ss -tlnp grep 8085`
④ 修复 kill 4060819 → reload → 再 ss / curl nginx 接管 8085,页面变"我的实战综合站"

三个关键认知:

  1. nginx -t 只查语法,不抢端口 ------它体检通过不代表服务能起来;真正抢端口发生在 reload 那一刻。
  2. reload 失败不会弄死现有服务 ------nginx 抢端口失败会放弃新配置、回滚保持旧配置继续营业(这次是例外:8085 还有 python 活着,所以 curl 到了 python,但其它端口的老配置毫发无损)。所以 reload 失败"还有救":先修好病因,再 reload 一次。
  3. 端口的主人用 ss -tlnp------看到 PID 就能顺藤摸瓜找到进程并处置。

杀进程用 kill PID;观察端口 ss -tlnp | grep 端口号。后端开发被"端口被占"卡住,这套组合拳是家常便饭。


五、火灾 3:权限问题(404/403)--- 门锁了

完整命令流程

bash 复制代码
# ── 注入(制造事故):给站点目录上锁,只有 root 能进 ──
sudo chmod 700 /var/www/mysite-front && ls -ld /var/www/mysite-front
# drwx------  ← 700 权限:www-data 连门都进不去

# ── ① 看证据:站点 403 ──
curl -sI http://127.0.0.1:8085/ | head -3
# HTTP/1.1 403 Forbidden
# Server: nginx/1.18.0 (Ubuntu)

# ── ③ 看日志:Permission denied 铁证 ──
sudo tail -3 /var/log/nginx/error.log
# "/var/www/mysite-front/index.html" is forbidden (13: Permission denied)

# ── ④ 修复:开锁(755 = 目录可进可读) ──
sudo chmod 755 /var/www/mysite-front && ls -ld /var/www/mysite-front
# drwxr-xr-x  ← 恢复

# ── 验证:立即可用,无需 reload! ──
curl -s http://127.0.0.1:8085/ | grep -i title
# 输出:<title>我的实战综合站</title>  ← 满血回归
四步 操作 现象
注入 chmod 700 /var/www/mysite-front(只有 root 能进) 站点 403
① 看证据 curl -sI HTTP/1.1 403 Forbidden
③ 看日志 tail /var/log/nginx/error.log "/var/www/mysite-front/index.html" is forbidden (13: Permission denied)
④ 修复 chmod 755 /var/www/mysite-front 立即恢复 200,无需 reload

403 vs 404 判读(本课最值钱的知识点):

响应 含义 日志里的差别
404 Not Found "地址不存在"------nginx 连路径都摸不到(上级目录都进不去,stat 失败) stat() failed (13: Permission denied)
403 Forbidden "人在但门锁了"------nginx 看得见文件,打开被拒绝 is forbidden (13: Permission denied)

核心认知:危险信号永远是同一个单词 Permission denied 权限链上任何一环断掉(/home/yfh 是 750、目录变成 700......),www-data 进不去就报错。

另一个关键认知:权限是文件系统的事,不是 nginx 配置的事------chmod 改完立即生效,不需要 reload!


六、三场火灾横向对比(背下来)

火灾 根因 危险信号 修复 要 reload 吗
语法错误 配置写错(缺 ; nginx -t 红字 改配置 ✅ 必须
端口冲突 端口被别的进程占 bind() failed (98) + ss 现形 kill 占位者 ✅ 必须
权限问题 目录/文件权限不够 Permission denied chmod 改权限 ❌ 不需要

共同套路:永远先看证据和日志定位根因,再动手。"改配置前先 nginx -t,动端口先 ss,权限问题先看 Permission denied。"


七、排障急救命令清单(复制即用)

bash 复制代码
# 1. 配置体检(改配置后必做)
sudo nginx -t

# 2. 重载配置(让新配置生效)
sudo systemctl reload nginx

# 3. 看错误日志(排障主战场)
sudo tail -50 /var/log/nginx/error.log

# 4. 看端口被谁占了
ss -tlnp | grep 端口号

# 5. 杀占位进程
kill PID

# 6. 验证服务真的活着(-sI 看响应头,-s 看正文,grep title 验明正身)
curl -sI http://127.0.0.1:端口/
curl -s  http://127.0.0.1:端口/ | grep -i title

# 7. 修权限(755 = 目录可进,644 = 文件可读)
sudo chmod 755 目录
sudo chmod 644 文件

# 8. 看文件权限(-d 看目录本身,一目了然)
ls -ld 目录

八、课程毕业总结

9 课打通 nginx 全链路:解剖架构 → 静态服务 → location 规则 → 反向代理 → 负载均衡 → HTTPS → 性能缓存 → 综合实战 → 排障急救

一个站点 = 一个配置文件里的多个 server 块(门);端口是门牌号;nginx -t 是体检、reload 是换班、error.log 是案发现场、ss 是找茬神器------以后任何服务"坏了",先证据,后日志,再动手。

相关推荐
前端玩坑坑1 小时前
View Transitions API 入门教程,优雅过度
前端
元界metalite1 小时前
MyBatis通用查询如何避免SELECT *?MetaLite如何按需返回字段
后端
Flynt2 小时前
Go 1.27 升了一波,泛型方法和 JSON v2 真香但有个坑
后端·go
李高钢2 小时前
WPF MVVM Light(三):RelayCommand 命令与 Messenger 消息
前端·c#·wpf
lichenyang4532 小时前
Socket.IO 原理与技术选型
前端
qq21084629532 小时前
在python中什么是 self 和 cls?
开发语言·前端·python
我会冲击波2 小时前
vibe coding 一个多月,我把 Claude Code + Pi 做成了桌面 IDE,还给它移植了 VS Code 的编辑体验
前端·javascript·后端
我是谁的程序员2 小时前
Windows / Linux / Mac 上不用 Xcode 把 IPA 上传到 App Store,upload 命令详解
后端·ios