迟到的故障公告:错误的缓存数据引起新版博客后台发布后的故障

10月18日晚上 22:00 ,咱们对处于灰度发布阶段的新版博客后台(Angular 8.2.7 + .NET Core 3.0)进行了一次发布操做,在发布后因为清除缓存 web api 的一个 bug 形成在发布后经过新版博客后台修改的博文没法访问(404错误);在发现问题后,咱们回退至发布以前的版本,可是因为 appsettings.Production.json 配置文件的不一致形成回退后的版本出现 500 错误;在修复配置文件问题后,在 docker swarm 集群上部署时又遭遇奇怪的容器健康检查失败的问题,屡次部署后才成功,直至 23:00 左右才恢复正常。web

很是抱歉,此次故障给使用新版博客后台的园友带来了很大的麻烦,请您谅解。docker

在此次发布中包含一个比较大但却没有引发咱们足够重视的变动,原先在博客后台代码中进行的清除 memcached 缓存(修改博文时清除对应的缓存)的操做改成调用 web api ,在实现清除缓存 web api 时因为没有足够重视在没有写集成测试覆盖的状况下就发布了,从而没有及时发现其中埋藏的一个 bug ,这个 bug 是由下面的 C# 代码引发的:json

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 ,故障所以而引起。api

针对此次故障,在修掉 bug 代码的同时咱们将采起如下改进措施:缓存

1)对从缓存中获取的数据进行校验并自动修复,这样即便出现错误的缓存数据,也能够减小对业务的影响。app

else if (blogPost.PostId != postId)
{
    blogPost = await GetBlogPostById(blogId, postId);
    await _cacheService.UpdateAsync(cacheKey, 3600, blogPost);
}

2)增强 Code Reviewmemcached

3)提升集成测试的覆盖率post

4)解决生产环境配置管理的问题测试

5)改用 k8s 部署生产环境spa

最近的新版博客后台发布故障暴露了咱们在团队开发能力上的落后,咱们正在努力改进与提高,但愿你们可以谅解咱们暂时的 low 。

相关文章
相关标签/搜索