【故障公告】發佈 .NET Core 版博客站點引發大量 500 錯誤

很是抱歉,今天上午的博客站點故障給你們帶來了很大的麻煩,請你們諒解。此次故障是咱們發佈 .NET Core 版博客站點引發的,雖然咱們進行了充分的準備,但仍是低估了高併發下的複雜問題。nginx

如下是故障背景與大體通過:web

在這個炎炎夏日,咱們正熱火朝天地忙着整個 .NET Core 遷移工程的收官 —— 發佈 .NET Core 版博客站點與博客後臺。咱們的其餘系統都早已遷移至 .NET Core 並已在線上工做一番時日,只剩下最難啃的硬骨頭 —— 博客系統,到這個月這根鋼鐵般堅硬的硬骨頭也被啃得差很少了,它的發佈上線將爲咱們整個 .NET Core 遷移工程畫上完美的句號,並順帶以此里程碑迎接 .NET Core 3.0 正式版的發佈。docker

因此,發佈 .NET Core 版博客站點與博客後臺成爲咱們8月份最重要的工做。.NET Core 版博客站點7月份就已經完成開發,這段時間一邊進行更進一步的內測,一邊進行灰度發佈,接入一些生產流量以發現咱們測試中未能發現的問題並進行修復,在上個週末接入更多生產流量進行測試與修復後,咱們已經頗有信心,評估後認爲已具有正式發佈條件,除了咱們沒法在測試環境中模擬的博客系統所處的複雜高併發場景。centos

因而一邊帶着信心,一邊帶着對高併發問題的擔憂,咱們決定在今天一大早進行發佈。服務器

發佈時的部署場景是這樣的,博客系統基於 .NET Core 3.0 Preview 7 (EF Core 用的仍是 3.0 Preview 5),7臺阿里雲 centos 服務器組建了 docker swarm 集羣,6臺4核8G服務器做爲 worker 節點跑博客站點的應用容器,1臺2核4G的服務器做爲 manager 節點(不部署任何容器),每一個 worker 節點都部署 1 個 nginx 與 .net core 博客應用容器,全部請求都由阿里雲均衡轉發到 nginx 容器,再由 nginx 容器轉發給 .net core 應用容器,nginx 經過端口映射的方式監聽 worker 節點服務器的 80 端口。網絡

這樣的部署環境也是咱們通過長期驗證的,惟一沒有通過驗證的就是博客系統這麼高的併發。併發

頂着2個高併發問題的風險(docker swarm 與 .net core ),咱們在今天早上 5:30 左右進行了發佈。curl

開始訪問量小,併發低,沒出現問題,但到 8:30 左右出現問題了,打開不少博客頁面要1秒多(正常狀況是幾十毫秒),而在容器內用 curl 命令請求都不到10毫秒。高併發

$ docker exec -t $(docker ps -f name=blog_web -q) curl -H 'X-Forwarded-Proto:https' -w %{time_total} -o /dev/null -s localhost 
0.002876

懷疑是 nginx 的問題,準備從新建立一個 docker 集羣,不用  nginx 直接用 kestrel 監聽 80 端口。性能

後來同事指出,不是 nginx 的問題,是 docker swarm 端口映射在高併發下的性能問題,只有將端口映射改成 host 網絡模式才能解決這個問題。

9:30 左右,隨着併發愈來愈高,nginx 容器開始報 500 錯誤,開始覺得是集羣中的服務器負載太高,因而向 docker swarm 集羣中添加服務器,但於事無補,500 錯誤愈來愈多。

出現 500 錯誤時,有時刷新一次就會好,有時要刷新好幾回,懷疑是集羣中某些服務器不穩定,因而一臺一臺登陸集羣中的服務器進入容器用 curl 命令進行測試,除了1臺服務器不穩定,其餘服務器 curl 命令測試時響應速度都正常,將那臺不太穩定的服務器下線,問題依舊,隨着併發量繼續增大,500 錯誤也繼續增多。

進一步分析後,懷疑 500 錯誤是由於高併發下 nginx 容器與 .net core 應用容器之間的網絡通訊出現問題,因而 10:30 左右決定放棄此次發佈,回退至跑在 Windows 上的 .net framework 版本博客站點,恢復了正常。

相關文章
相關標籤/搜索