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 。