遲到的故障公告:錯誤的緩存數據引起新版博客後臺發佈後的故障

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 。

相關文章
相關標籤/搜索