迟到的故障公告:错误的缓存数据引发新版博客后台发布后的故障
10月18日晚上 22:00 ,我们对处于灰度发布阶段的新版博客后台(Angular 8.2.7 + .NET Core 3.0)进行了一次发布操作,在发布后由于清除缓存 web api 的一个 bug 造成在发布后通过新版博客后台修改的博文无法访问(404错误);在发现问题后,我们回退至发布之前的版本,但是由于 appsettings.Production.json 配置文件的不一致造成回退后的版本出现 500 错误;在修复配置文件问题后,在 docker swarm 集群上部署时又遭遇奇怪的容器健康检查失败的问题,多次部署后才成功,直至 23:00 左右才恢复正常。
非常抱歉,这次故障给使用新版博客后台的园友带来了很大的麻烦,请您谅解。
在这次发布中包含一个比较大但却没有引起我们足够重视的变更,原先在博客后台代码中进行的清除 memcached 缓存(修改博文时清除对应的缓存)的操作改为调用 web api ,在实现清除缓存 web api 时由于没有足够重视在没有写集成测试覆盖的情况下就发布了,从而没有及时发现其中埋藏的一个 bug ,这个 bug 是由下面的 C# 代码引起的:
await _cacheService.RemoveAsync(CacheKeyManager.GetBlogPost(blogId.Value, postId.Value)); var post = await blogPostService.GetCachedPostById(blogId.Value, postId.Value); //... if (post.DisplayOnHomePage) { await ClearHomePostsList(blogId.Value); } //..
上面的代码中在清除所修改博文的缓存后,又获取该博文进一步清除与该博文相关联的缓存,调用 GetCachedPostById 方法时又创建了缓存,但由于实现时漏写了 DTO 映射配置代码,造成缓存的 BlogPostDto 字段值不完整从而 PostId 的值为 0 。在我们的缓存机制中,对于不存在的博文,会 new 一个空的 PostId 为 0 的 BlogPostDto 放入缓存,所以 PostId 为 0 的缓存数据都当作不存在的博文直接响应 404 ,故障因此而引发。
针对这次故障,在修掉 bug 代码的同时我们将采取以下改进措施:
1)对从缓存中获取的数据进行校验并自动修复,这样即使出现错误的缓存数据,也可以减少对业务的影响。
else if (blogPost.PostId != postId) { blogPost = await GetBlogPostById(blogId, postId); await _cacheService.UpdateAsync(cacheKey, 3600, blogPost); }
2)加强 Code Review
3)提高集成测试的覆盖率
4)解决生产环境配置管理的问题
5)改用 k8s 部署生产环境
最近的新版博客后台发布故障暴露了我们在团队开发能力上的落后,我们正在努力改进与提升,希望大家能够谅解我们暂时的 low 。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· autohue.js:让你的图片和背景融为一体,绝了!
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
2017-11-20 上周热点回顾(11.13-11.19)