Django刷新页面时模板未同步数据库新数据故障排查
- 数据写入链路正常:通过前台表单、Django admin提交数据修改请求时,数据可正确写入sqlite数据库
- 普通用户视图数据不一致:提交修改后重定向至其他视图、或按F5刷新页面时,面向普通用户的视图无法展示最新数据变更,必须重新登录会话、清除Cookie后才能加载到更新后的内容
- admin视图无异常:Django admin后台页面仅需按F5刷新即可正常展示最新数据
- 故障属性:站点已稳定运行1年以上,该问题为突发故障,此前无同类问题记录
- 进程管理组件:Stevedore
- 反向代理:Nginx
- WSGI服务:gunicorn 20.0.4
- 后端框架:Django 3.1.4
- 运行时版本:Python 3.9
- 数据库:sqlite 3
- 前端依赖:Bootstrap 4.6
- 排除浏览器缓存因素:在多款不同浏览器中测试均可稳定复现问题
- 已检索公开技术论坛,暂未找到匹配的同类问题解决方案
- 第一优先级排查视图/中间件缓存配置异常
对比普通用户视图与admin视图的缓存配置差异:重点检查普通用户视图是否错误配置了基于Cookie/会话维度的缓存规则,包括
cache_page装饰器参数错误、自定义缓存中间件失效逻辑未触发、缓存过期时间配置异常的情况。可临时给出现问题的普通用户视图加上@never_cache装饰器测试,如果加装饰器后可正常返回最新数据,即可锁定为缓存层问题,再逐层排查是Django层缓存、还是自定义代码逻辑返回了缓存的旧响应。 - 第二优先级排查gunicorn多worker下的sqlite一致性问题
sqlite为文件型数据库,在gunicorn多worker模式下如果配置了数据库长连接,会出现部分worker持有的数据库连接未感知到文件写入、持续读取旧数据快照的问题。重点核对近期是否调整过gunicorn的worker数量、worker类型参数,检查Django数据库配置中的
CONN_MAX_AGE参数是否被错误修改为非0值开启了长连接,且未配置连接自动回收逻辑。可临时将gunicorn worker数量调整为1测试,如果单worker下问题消失,即可定位为多worker下sqlite连接一致性问题,调整数据库连接配置即可修复。 - 第三优先级排查Nginx反向代理缓存误配置
检查Nginx配置中是否针对普通用户访问的路由路径错误开启了
proxy_cache缓存,且缓存key绑定了用户Cookie标识,导致用户在同一会话下持续命中Nginx层存储的旧缓存响应;而admin路径未匹配缓存规则,所以可正常回源获取最新数据。可临时绕过Nginx直接访问gunicorn端口测试普通用户视图,如果直连时数据正常,即可锁定为Nginx配置问题,修正对应路由的缓存规则即可。 - 第四优先级排查近期上线的自定义逻辑变更
核对故障出现前的代码、配置变更记录,重点检查新增/修改的自定义中间件、上下文处理器、全局响应拦截逻辑,是否存在针对已登录用户提前返回历史响应、未执行正常数据库查询流程的问题。
内容的提问来源于stack exchange,提问作者Carras

