1. 这次排查是从一句很模糊的反馈开始的
用户侧看到的现象通常很模糊:“有时候能打开,有时候不行”。这句话听起来像网络波动,也像浏览器缓存,还可能是 DNS、证书、代理或服务器权限问题。 如果直接凭感觉改配置,很容易把本来正常的部分也改坏。
我先把现象拆成更具体的问题:到底是根域名打不开,还是博客子域名打不开;是首页打不开,还是文章页打不开;是 Edge 不行,还是所有浏览器都不行; 是返回 404、502、超时,还是 TLS 报错。问题越具体,后面的命令才越有意义。
2. 我习惯先把访问链路分成五层
这类问题最怕混在一起看。浏览器缓存、系统 DNS、反向代理、宿主机 Nginx、静态文件目录,每一层都有可能让用户看到“打不开”。 我会按从外到内的顺序排查,避免一开始就钻进服务器配置。
- 浏览器层:是否命中旧缓存,是否有旧的 HSTS、站点数据或扩展干扰。
- DNS 层:blog 子域名是否稳定解析到服务器公网 IP。
- 代理层:Nginx Proxy Manager 是否把请求转发到正确目标。
- 静态服务层:宿主机 Nginx 是否能读取对应路径。
- 文件系统层:目录和文件权限是否允许 Nginx 用户访问。
curl -I https://blog.020814.xyz/
curl -I https://blog.020814.xyz/posts/index.html
curl -I https://blog.020814.xyz/posts/vps-infra.html
当首页返回 200,而文章页返回 404 或 403 时,方向就已经收窄了:域名和证书大概率没问题,重点应该放到文章路径、Nginx try_files 和文件权限上。
3. 看响应头和日志,比猜浏览器缓存有效得多
如果只在浏览器里刷新,很容易被本地缓存和扩展影响。命令行请求可以绕开大部分干扰,直接看到服务器返回了什么。
我通常先用 curl -I 看状态码和响应头,再去服务器上看 Nginx error log。
# 看公网访问结果
curl -k -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://blog.020814.xyz/posts/index.html
# 看宿主机静态服务是否正常
curl -I http://127.0.0.1:8080/posts/index.html
# 看最近的 Nginx 错误
tail -n 80 /var/log/nginx/error.log
这次日志里最关键的线索是 Permission denied。这说明请求路径存在,但 Nginx 无法进入或读取对应目录。
它不是典型的缓存问题,也不是 DNS 问题,而是文件系统权限问题。
4. 真正的问题是 posts 目录权限过严
最终定位到的现象是:站点根目录下的首页文件可以被读取,但 posts 目录权限过严,导致 Nginx 不能进入目录读取文章页。
这就解释了为什么“主页有时看起来正常,点文章就不行”。主页和文章页走的是同一个域名,却落到了不同文件路径。
# 修复静态站点的常规读取权限
find /var/www/junhao-blog -type d -exec chmod 755 {} +
find /var/www/junhao-blog -type f -exec chmod 644 {} +
# 检查配置并重新加载
nginx -t
systemctl reload nginx
修复后,我没有只看浏览器,而是分别验证首页、归档页和具体文章页。只有这些关键路径都连续返回 200,才算真正修好。
5. 后续我用这几个动作避免它再出现
- 上传或解压新页面后,统一检查目录 755、文件 644。
- 每次更新后同时验证首页、归档页、文章页和静态资源。
- 遇到浏览器差异时,先用命令行请求确认服务器真实返回。
- 保留 Nginx access log 和 error log,不把日志当成可有可无。
- 用户侧仍异常时,再处理浏览器缓存、DNS 缓存和 Edge 站点数据。
排障复盘的价值不只是“这次修好了”,而是下次遇到类似现象时,我能更快判断它属于哪一层。 对个人服务器来说,这种可重复的排查路径,比记住某一条命令更重要。