☰
👁️ 预览
取消
💾 保存
C
Claude
▾
C
Claude
claude@note.center
🔔
消息通知
🔄
账号切换
⚙️
设置
🚪
退出登录
Markdown
富文本
# 网站缓存问题的运维排查方法 > 零基础入门,通过三个实战场景学习缓存排查的完整方法论 --- ## 🧠 核心思维:先找"矛盾" 排查缓存问题,本质上就是做一件事: > **找到"用户看到的"和"实际数据"之间的不一致** 然后顺着不一致,一层一层往上追。 --- ## 场景一:应用层缓存(笔记内容不更新) ### 故事 一个记事本网站,修改笔记内容后保存成功,但刷新页面还是旧内容。 ### 排查过程(一步步来) **第 1 步:确认现象** ```bash # 看页面显示什么 curl http://localhost:5000/note/1 # 结果:旧标题 "入职第一天备忘" (v1) # 改内容 curl -X POST http://localhost:5000/update/1 \ -d "title=已修改的标题" # 再看页面 curl http://localhost:5000/note/1 # 结果:还是旧标题 "入职第一天备忘" (v1) ❌ ``` **第 2 步:是不是浏览器缓存?** ```bash #curl 请求一次——如果 curl 返回的是对的,那说明是浏览器缓存的问题;如果 curl 返回的也不对,那说明问题在服务器这边。 #curl 默认不缓存,但结果还是旧的 → 排除浏览器缓存 ``` **第 3 步:查响应头** ```bash curl -I http://localhost:5000/note/1 # 发现:Cache-Control: public, max-age=60 # 服务器告诉浏览器"缓存 60 秒" ``` **第 4 步:清空服务端缓存试试** ```bash # 清空缓存后,页面显示正常 → 确认问题在服务端缓存 怎么清理缓存: 1. 重启服务(最粗暴但管用) # 找到进程,杀掉,重新启动 kill <进程ID> python3 app.py 所有内存里的缓存随着进程一起清空。 怎么找到进程?最常用的几个命令: # 方式一:按端口找(最常用) lsof -i :5000 # 结果:COMMAND PID ... # python 12345 # 方式二:按进程名找 ps aux | grep python # 结果:root 12345 ... python3 app.py # 方式三:按端口找(上面的简化版) lsof -t -i :5000 # 结果:12345 ← 只输出 PID,适合配合 kill 用 # kill $(lsof -t -i :5000) 2. 应用提供了清缓存接口(像我们实验里的) curl http://localhost/debug/flush-cache # 或者浏览器访问 /debug/cache 然后点"清空所有缓存" 3. 用专门的缓存管理命令 # Redis 缓存 redis-cli FLUSHALL # Nginx 缓存目录 rm -rf /var/cache/nginx/* ``` **第 5 步:找到根因** 看代码,发现 `invalidate_note_cache()` 函数里负责清理缓存的代码被注释掉了: ```python def invalidate_note_cache(note_id): if cache_key in note_cache: # del note_cache[cache_key] ← 这一行被注释了! pass ← 什么都没做 ``` **第 6 步:修复** 取消注释,让清理逻辑真正执行。同时把 `Cache-Control: max-age=60` 改成 `no-cache`,让浏览器每次重新验证。 ### 要点 - 数据更新后,缓存也要跟着清 - 排查时用 curl 可以排除浏览器缓存的干扰 - 响应头里的 `Cache-Control` 是第一时间要看的 --- ## 场景二:静态资源缓存(改 CSS 按钮颜色不生效) ### 故事 后台系统的"提交工单"按钮是蓝色的,UI 改成绿色并部署了,但刷新页面按钮还是蓝色。 ### 排查过程 **第 1 步:确认服务器上的 CSS 是否已更新** ```bash curl http://localhost:5002/static/style.css | grep btn-submit # 结果:background-color: #5cb85c(绿色)✅ 服务器已更新 ``` **第 2 步:查看 CSS 的响应头** ```bash curl -I http://localhost:5002/static/style.css # Cache-Control: public, max-age=86400 ← 缓存 24 小时! # Expires: Wed, 01 Jul 2027 ← 缓存到 2027 年! ``` 问题找到了:浏览器被要求缓存这个 CSS 文件 24 小时,即使服务器更新了,浏览器也不会重新请求。 **第 3 步:为什么没加版本号?** HTML 里引用 CSS 的方式: ```html <link rel="stylesheet" href="/static/style.css"> ← 没有版本号 ``` 部署后 URL 不变,浏览器直接用缓存。 **第 4 步:修复** 改成带版本号的引用: ```html <link rel="stylesheet" href="/static/style.css?v={{ css_version }}"> ``` 部署新版时版本号变了,URL 变了,浏览器就会重新请求。 ``` 部署前 → /static/style.css?v=1 部署后 → /static/style.css?v=2 ← URL 不同,浏览器重新下载 ``` ### 要点 - CSS/JS 等静态资源适合长缓存(提高加载速度),但要用版本号解决更新问题 - 版本号可以加在 URL 参数里(`?v=2`),也可以改文件名(`style.v2.css`) --- ## 场景三:反向代理缓存(更新公告不生效) ### 故事 运维后台有个公告横幅,管理员更新了公告内容,但通过代理访问还是旧的。 ### 架构 ``` 用户 → 代理层(模拟 Nginx):5004 → 后端应用:5003 ``` ### 排查过程 **第 1 步:对比两条"路"的结果** ```bash # 直接访问后端(最新数据) curl http://localhost:5003/ → "服务器正在维护" ✅ # 通过代理访问 curl http://localhost:5004/ → "系统正常运行中" ❌ 还是旧的! # 代理返回的响应头 curl -I http://localhost:5004/ | grep X-Cache # X-Cache: HIT ← 代理缓存命中,没去后端取 ``` **第 2 步:定位问题** 代理层有自己的缓存。后端更新了数据,但代理不知道,还在返回旧的缓存内容。 **第 3 步:修复** 代理在转发更新请求到后端之后,也顺手清理自己的缓存: ```python def proxy_update(): # 转发到后端 forward_to_backend(...) # 清理代理自己的缓存 ← 原来这行被注释掉了 if "index_page" in proxy_cache: del proxy_cache["index_page"] ``` ### 要点 - 有多层架构时,数据更新要联动机所有缓存层 - `X-Cache: HIT` 表示代理缓存命中,是排查代理层问题的关键线索 - 对比不同路径(直接 vs 通过代理)能快速定位问题在哪一层 --- ## 场景四:配置文件热加载(改配置文件不生效) ### 故事 系统公告写在配置文件里。运维改了配置文件,但页面上还是旧的公告。 ### 排查过程 **第 1 步:确认改文件是否成功** ```bash cat /root/cache-lab/config/app.conf # site_notice = 系统已恢复正常运行 ✅ 文件确实改了 ``` **第 2 步:看页面显示什么** ```bash curl http://localhost:5005/ # "系统正在例行维护,预计 18:00 恢复" ❌ 还是旧的 ``` **第 3 步:查线索** 页面底部显示: ``` 配置加载时间: 2026-06-30 23:54:26 ``` 这个时间是应用启动的时间,说明应用只在启动时读了一次配置。 **第 4 步:修复** 方式一:手动重载配置(应用提供 `/config/reload` 接口) 方式二:重启服务 方式三:实现热加载(自动检测文件变化) ### 要点 - 配置文件更改后,应用需要重新读取才能生效 - 不是所有应用都支持热加载,运维要了解应用的配置读取机制 - 检查"加载时间"是一个快速判断的技巧 --- ## 📋 三个场景的共通排查法 不管遇到什么缓存/配置问题,套路是一样的: ``` ① 找矛盾 → "用户看到的" vs "实际数据" 不一样 ② 定层级 → 问题在浏览器?代理?应用层?配置文件? ③ 查原因 → 为什么这个层级还在用旧数据? ④ 修联动 → 数据变了,所有相关环节都要更新 ``` ### 我的学习心得 | 场景 | 现象 | 根因 | 修复 | |------|------|------|------| | 笔记不更新 | 改了内容看不到 | 服务器缓存没清 | 更新时清理缓存 | | CSS 按钮不变 | 改了样式看不到 | 浏览器缓存 24h + 没版本号 | URL 加 `?v=版本` | | 公告不变 | 改了文件还是旧的 | 应用启动时只读一次配置 | 提供重载机制 | | 代理返回旧内容 | 后端更新了,代理返回旧的 | 代理缓存和后台不同步 | 更新数据时清代理缓存 | ### 实用排查命令速查 ```bash # 查响应头 curl -I URL # 跳过缓存请求 curl -H "Cache-Control: no-cache" URL # 对比不同路径(绕过代理) curl http://代理地址/ curl http://后端地址/ # 查看缓存状态 curl http://服务地址/debug/cache # 看服务器日志 grep "cache\|缓存\|清理" /var/log/app.log 日志怎么看 # 1、看最后几行(最常用) tail -20 /var/log/nginx/access.log # 2、实时跟踪(debug 时最有用) tail -f /var/log/nginx/access.log # Ctrl+C 退出 # 一边操作一边看日志刷出来 # 3、搜索关键词 grep "ERROR" /var/log/myapp/app.log # 4、翻页看大文件(日志很大的时候) less /var/log/nginx/access.log # 按 j/k 上下翻,按 q 退出 # 按 / 搜关键词,按 n 跳到下一个 用文件重定向存到了 /tmp/ 下面:cat /root/cache-lab/scenario1_css.py &>/tmp/css-lab.log & 所以实验中我们用 grep "缓存" /tmp/cache-lab.log 来看 # 看配置加载时间 grep "加载\|loaded\|startup\|init" 页面内容 ```
预览
编辑内容后实时预览...