Memcached 的惹禍,.NET 5.0 的背鍋


抱歉,拖到現在才寫這篇為 .NET 5.0 洗白的博文(之前的博文),不好意思,又錯了,不是洗白,是還 .NET 5.0 的清白。

抱歉,就在今天上午寫這篇博客的過程中,由於一個bug被迫在訪問高峰發布,在10:30~11:10再次引發上次遇到的同樣故障,由此給您帶來麻煩,請您諒解。

2020年10月14日晚上我們發布了升級至 .NET 5.0 RC 2 的博客系統,在正式版發布之前進行升級不是我們想追求前衛,而是因為:

  1. 微軟官博已經說明可以用於生產環境

RC2 is a “go live” release; you are supported using it in production.

  1. 正則表達式性能大幅提升(Regular expression performance improvements

On many of the expressions we’ve tried, these improvements routinely result in throughput improvements of 3-6x, and in some cases, much more.

  1. Json 序列化性能提升

JsonSerializer performance is significantly improved in .NET 5.0.

  1. 想使用 EF Core 5.0 的新特性(What's New in EF Core 5.0

最吸引我們的是第2點,博客系統的代碼中用了很多正則表達式,是耗CPU大戶。

而且升級很簡單:

  • TargetFramework 由 netcoreapp3.1 改為 net5.0
  • 更新 nuget 包
  • 容器鏡像 mcr.microsoft.com/dotnet/core/sdk:3.1 改為 mcr.microsoft.com/dotnet/sdk:5.0mcr.microsoft.com/dotnet/core/aspnet:3.1 改為 mcr.microsoft.com/dotnet/aspnet:5.0

發布后從第2天上午訪問高峰的監控數據看,CPU消耗降了10%,效果不錯。

輕松升級,提前享受 .NET 5.0 的性能提升,印象中這是我們在 .NET Core 大版本升級歷史中最愜意的一次。

下午我們帶着升級后的喜悅心情歡迎新人的加入,現在能夠遇到有興趣學習 .NET 的新人也是不容易的,好了,現在可以直接學 .NET 5.0 了。就在新人歡迎會期間,網站出現了故障,昨晚升級到 .NET 5.0,今天下午就出故障,最大的嫌疑對象顯然是 .NET 5.0,當機立斷地進行回退操作,如果回退到升級之前的版本能恢復正常,那 .NET 5.0 就罪責難逃。

用下面的腳本在k8s集群上將部署回退到升級之前的容器鏡像

./deploy-blog.sh 2.3.73 

回退完成之后,很快恢復正常,鐵證如山,隨后我們立即發博宣判——博客系統升級到 .NET 5.0 引發的故障,讓還未正式出茅廬的 .NET 5.0 就背上一口沉重的鍋。

幸好有開發同事沒有這么片面地看待問題,對故障進行了進一步分析,發現故障與 memcached 服務器的 tcp 連接數異常高有關,大量的數據庫連接超時是因為連不上 memcached (達到了1萬的最大連接數限制)造成大量請求直接訪問數據庫引起的。更進一步地,還找到了重現問題的方法,多次點擊某些博客,就能讓 memcached tcp 連接數飆升,排查后發現這些博客需要被緩存的數據超過了1M,超出了 memcached 單個緩存項的大小限制(默認就是1M),造成數據永遠無法被緩存,但每次都要徒勞地讀寫 memcached 服務器。我們針對這個問題進行了修復,修復后重新發布了 .NET 5.0 版,觀察幾天后沒有再次出現故障。

我們錯怪了 .NET 5.0,我們的一時武斷讓 .NET 5.0 在即將出道之前先背鍋,我們向 .NET 5.0 說抱歉,向被誤導的 .NET 開發者說抱歉,我們會吸取教訓,在故障發生后不要急於發博文,先全面分析問題,不能因為我們的一時誤判產生誤導。

雖然修復了問題,用上了 .NET 5.0,但問題背后的真正原因至今沒有弄明白——僅僅幾次鼠標點擊,緩存數據超過1M,就能讓 memcached 服務器的 tcp 連接數飆升?可能與我們使用的 memcached 客戶端 EnyimMemcachedCore,待以后再找時間研究。

今天在寫這篇博文的期間,再次遇到這個故障,看來有緣分,想躲也躲不過去了。今天發生故障與訪問高峰發布有關,但之前我們評估過訪問高峰發布的影響,也就5-10分鍾左右訪問速度變慢,不會產生如此大的重創。這次故障與上次是同樣的表現,memcached tcp 連接數異常高,頻頻達到1萬的最大連接數限制,打開網頁速度慢就是因為在等待與 memcached 服務器建立 tcp 連接,重啟 memcaced 服務器也於事無補,很快就會再次飆升至1萬,平時訪問高峰也就5000左右的連接。

從 memcached 服務器的其他指標看,雖然上萬的 tcp 連接,但並沒有不堪重負,難道僅僅是車多路窄造成的堵車引起大家都通行緩慢?那把路拓寬不就行了,於是將 memcached 服務器的 tcp 最大連接數限制由1萬拓寬到2萬,本擔心連接數會飆升到2萬,但沒想到竟然恢復正常了。可能是某種特殊情況造成需要稍過萬的 tcp 連接,但最大連接數限制把大家都堵住了,看來代碼世界也最怕堵車。

今天集中3個多小時的時間才完成這篇粗糙的博文,在故障后分享一篇博文也不是一件容易的事。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM