暴風雨中的 online :.net core 版部落格站點遭遇的高併發問題進展
今天暴風雨襲擊了杭州,而昨天暴風雨(高併發問題)席捲了園子,留下一片狼藉。
在前天傍晚,我們進行了 .net core 版部落格站點的第二次釋出嘗試,在釋出後通過 kestrel 直接監聽取代 nginx 轉發解決了高併發下的1秒延遲問題,成功地頂住了下班前的訪問小高峰,但這只是一場大雨,第二天的上午和下午的暴風雨(訪問高峰中的高併發)才是真正的考驗。
昨天,面對暴風雨,我們哼都不敢哼一聲“讓暴風雨來得更猛烈些吧”,只是一直不停地默唸“讓暴風雨快點過去吧”,尤其在下午的暴風雨襲擊下,跑在 docker swarm 上 .net core 版部落格系統潰不成軍,大量請求響應速度極不穩定,時而快如閃電(10ms左右),時而慢如蝸牛(10s, 30s 甚至超時)。與第一次釋出時不一樣,不僅部落格應用容器外是暴風雨,容器內也是暴風雨,在容器內用 curl 命令訪問與外部用瀏覽器訪問問題一樣(難不成真的是 docker swarm 網路的問題?kestrel 監聽取代 nginx 轉發只是將網路併發負載從 nginx 容器轉到了 kestrel 所在的部落格應用容器。。。有待驗證。)
昨天 17:30 左右併發量回落到一定程度之後,暴風雨飄然而去,園中立刻風平浪靜,晴空萬里,下午的那場暴風雨宛如夢中。
在暴風雨過後,我們查看了伺服器的 linux 系統日誌,發現很多下面的日誌,而且都發生在暴風雨期間。
Aug 8 15:57:12 blog-swarm-n3 kernel: nf_conntrack: table full, dropping packet Aug 8 15:57:12 blog-swarm-n3 kernel: nf_conntrack: table full, dropping packet Aug 8 15:57:12 blog-swarm-n3 kernel: nf_conntrack: table full, dropping packet
當時 docker swarm 叢集中一共5臺 worker 節點伺服器,統計了一下每臺伺服器出現 "table full" 日誌的數量。
blog-swarm-n3: 2149 blog-swarm-n4: 1964 blog-swarm-n5: 2451 blog-swarm-n6: 2095 blog-swarm-n7: 0
咦,怎麼有1臺伺服器為0?哦,原來是這臺沒有掛上所有負載均衡,只承受了 2/3 左右的流量,雖然下的暴風雨,但對這臺伺服器來說只是一場大雨。
針對上面的日誌,昨天我們晚上我們調整了 linux 核心的 2 個設定置(參考文件),在 /etc/sysctl.conf 中新增
net.netfilter.nf_conntrack_max = 655350 net.netfilter.nf_conntrack_tcp_timeout_established = 1200
這個調整成為我們今天唯一的希望,但早上訪問高峰來臨的時候,迎接我們的不是喜出望外,而是昔日重來。。。
在熟悉的暴風雨面前,我們面臨著艱難的選擇,放棄-退回 windows 上的 .net framework 版部落格系統,還是堅持-至少要找到一種能抵擋一定程度暴風雨的臨時解決方法?
那臺沒有 "table full" 日誌的伺服器給了我們啟發——分而治之,將暴風雨變成每一臺伺服器的大雨,拆分流量到不同的伺服器,減少每臺服器的併發連線數,今天就是通過這個臨時的笨方法扛住了暴風雨,大量減少了響應速度慢的情況,所以到現在 .net core 版部落格站點依然線上。
在抗過了今天上下午訪問高峰的暴風雨後,杭州也被暴風雨襲擊了,因為有了房子,任憑外面風吹雨打,我們可以坐在房間裡一邊敲著程式碼,一邊凝聽窗外的風聲雨聲。對於這次遇到的高併發問題,我們相信總有一天會為我們的部落格系統建造好房子,在暴風雨的風吹雨打中瀟灑地在日誌中寫著“讓暴風雨來得更猛烈些吧”。