
不知道差友們還記不記得,去年的 7 月 13 日,B 站發(fā)生了一件大事。它毫無(wú)征兆的崩了。。。( 如果忘了的小伙伴,可以看這篇文章)
至于為啥崩了,當(dāng)時(shí)大家誰(shuí)也心里沒(méi)個(gè)底。不過(guò)吹起水來(lái)可是一套一套的,什么停電啊,起火啊,程序員 rm -rf /* 跑路啊。。。說(shuō)的是個(gè)天馬行空。
后來(lái)呢,隨著 B 站在凌晨?jī)牲c(diǎn)一頓修仙,把服務(wù)器問(wèn)題給慢慢解決,這件事情也算是告一段落了。
【資料圖】
本以為這次 B 站崩了會(huì)和微博上無(wú)數(shù)崩了的網(wǎng)站一樣,成為我們沖浪生活中的一個(gè)笑談,僅留下一個(gè)大會(huì)員給我們“ 緬懷 ”。
沒(méi)想到在今年的 7 月 13 日,B 站特意發(fā)了一篇文章,刨開(kāi)心窩子來(lái)給我們講了一講,那個(gè)晚上,到底發(fā)生了什么。
咱也看了一下這篇文章,好家伙,讓整個(gè) B 站崩潰的原因,竟然只是一行代碼沒(méi)寫(xiě)好???借著這篇文章,世超準(zhǔn)備帶大家從B 站的角度來(lái)回顧一下這件事情。放心,不會(huì)有生澀難懂的名詞,不會(huì)有犀利糊涂的黑話,保證小白也能看明白。 案情回溯:意外,發(fā)生在 2021 年 7 月 13 日的 22 時(shí) 52 分。
負(fù)責(zé)搞定站點(diǎn)可靠性的工程師(SRE)和B站的客服都收到了大量網(wǎng)站打不開(kāi)的報(bào)警。
而負(fù)責(zé)處理這些事故的同事已經(jīng)下班了,當(dāng)即準(zhǔn)備在家里通過(guò) VPN 來(lái)登錄公司內(nèi)網(wǎng)處理這些問(wèn)題。
結(jié)果發(fā)現(xiàn)VPN也崩了。。。壓根進(jìn)不去系統(tǒng)。最后,還是在公司的整了個(gè) “ 綠色通道 ” 才成功進(jìn)去。你說(shuō)這綠色通道不會(huì)是向日葵吧(一種遠(yuǎn)程桌面軟件)
▼
而在綠色通道成功打通,負(fù)責(zé)各種業(yè)務(wù)的團(tuán)隊(duì)就位之后,B 站也開(kāi)始對(duì)問(wèn)題進(jìn)行分析定位。出問(wèn)題的模塊也很明顯,在線業(yè)務(wù)主機(jī)房的7層 SLB(負(fù)載均衡服務(wù)器,用來(lái)處理多用戶,多業(yè)務(wù)的情況)的 CPU 跑滿了 100%。
簡(jiǎn)單來(lái)說(shuō),就是 CPU 被不知道哪里來(lái)的刺客給占用光了算力,沒(méi)法處理業(yè)務(wù)了。
系統(tǒng)未響應(yīng).exe▼
B 站最開(kāi)始的嘗試方法呢,和咱們平時(shí)手機(jī)電腦卡機(jī)后做的操作一樣。
重啟就完事了,要相信重啟能解決 90% 的問(wèn)題!
但很可惜,B 站這次是那個(gè) 10.5%。
說(shuō)業(yè)務(wù)恢復(fù)了嘛,也沒(méi)有,主機(jī)房重啟后還是出現(xiàn)了CPU 跑滿 100%的問(wèn)題。不過(guò)別的機(jī)房好起來(lái)了,雖然會(huì)卡,但是沒(méi)出現(xiàn) CPU 跑滿的問(wèn)題。
有一部分做了多活的業(yè)務(wù)(多站點(diǎn)同時(shí)提供服務(wù))開(kāi)始慢慢恢復(fù)。所以。。。重啟不能完全解決問(wèn)題,但是這個(gè)問(wèn)題既然過(guò)去沒(méi)出現(xiàn)過(guò)。
那會(huì)不會(huì)是新加入的代碼問(wèn)題呢?隨著時(shí)間在一分一秒的過(guò)去,借助分析工具的幫助,問(wèn)題被定位到了最近新上線的 Lua(一種編程語(yǔ)言,類(lèi)似 Python,Java 這些)函數(shù)上。
隨后,B 站開(kāi)始進(jìn)行了一波波緊張的回滾操作。
這一通工作弄下來(lái),雖然好像找到幾個(gè)疑似出問(wèn)題的部位,但服務(wù)器還是該掛掛,距離 “ 康復(fù) ” 還有那么一些距離。
沒(méi)辦法,總得讓業(yè)務(wù)先跑起來(lái)吧。于是團(tuán)隊(duì)開(kāi)始兵分兩路。一隊(duì)繼續(xù)堅(jiān)持排查問(wèn)題,尋找原因,另一隊(duì)則是開(kāi)始重建一個(gè)新的 SLB 服務(wù)。
在緊張刺激的一小時(shí)后,新的 SLB 配置成功,原本導(dǎo)向主站的流量也慢慢的開(kāi)始遷移過(guò)去。
好在這次行了。
凌晨?jī)牲c(diǎn),在崩潰了三小時(shí)之后,B 站的業(yè)務(wù)總算得到了恢復(fù)。罪魁禍?zhǔn)祝荷厦孢@些,就是那個(gè)晚上 B 站發(fā)生的故事,雖然解決了表面問(wèn)題,讓業(yè)務(wù)恢復(fù)了。
可是最根本的原因是啥呢?如果不找到根因,那遲早會(huì)二度暴雷。
負(fù)責(zé)排查問(wèn)題的同學(xué)也沒(méi)讓人失望,在時(shí)間壓力大大放緩之后,找出了真相。沒(méi)有外星人,沒(méi)有起火,沒(méi)有斷電,和網(wǎng)友們想象的大相徑庭。B 站這次崩的根因,僅僅是因?yàn)橐粋€(gè)求最大公約數(shù)的函數(shù)沒(méi)寫(xiě)好。。。
咱先盤(pán)一下這個(gè) “ 萬(wàn)惡之源 ” 哈。
這是一個(gè)典型的 “自己調(diào)用自己 ” 的遞歸函數(shù)。a b兩數(shù)字輾轉(zhuǎn)求余,直到b 等于 0的時(shí)候函數(shù)終止。不然這個(gè)函數(shù)就會(huì)自己調(diào)用自己,重新再跑一遍。
看上去好像是一點(diǎn)點(diǎn)問(wèn)題都沒(méi)有,既明確了遞歸的終止條件(b = 0),也沒(méi)有太多復(fù)雜的邏輯處理。但是既然事情能發(fā)展到這地步。。。那就說(shuō)明是出大問(wèn)題了。對(duì)編程有些了解的差友可能發(fā)現(xiàn)了不對(duì):
你傳進(jìn)去的 0,是個(gè)什么 0?沒(méi)錯(cuò),在編程語(yǔ)言里,數(shù)字 0 和字符串 ‘ 0 ’并不算是一個(gè)東西。為了防止呆呆的計(jì)算機(jī)語(yǔ)言把事情給搞混,像 C 語(yǔ)言,Java 這些靜態(tài)語(yǔ)言都會(huì)要求我們?cè)趧?chuàng)建新變量的時(shí)候聲明這個(gè)變量的類(lèi)型。
搞清楚它到底是整數(shù),還是小數(shù),或者是一個(gè)字符。然而 Lua 是個(gè)非常智慧的語(yǔ)言,它沒(méi)有這個(gè)要求。麻煩的臟活累活讓它自動(dòng)來(lái)做就好了,Lua 會(huì)根據(jù)程序的需求自動(dòng)分配變量類(lèi)型。
C語(yǔ)言示例:# 定義一個(gè)整型數(shù)據(jù)a,為它賦值1# 定義一個(gè)字符串?dāng)?shù)據(jù)b,為它賦值‘1’int a = 0;char a = "0";Lua示例:--定義 a 為數(shù)字0,b為字符串‘0’a = 0b = "0"
所以,我們給參數(shù) b 傳進(jìn)去的數(shù)值,是數(shù)字 0呢,還是字符 ‘ 0 ’?一旦前面數(shù)據(jù)驗(yàn)證沒(méi)把好關(guān),在執(zhí)行某個(gè)功能的時(shí)候,把字符 ‘ 0 ’給傳到了這個(gè)函數(shù)里。
地雷就被引爆了。字符串‘0’不會(huì)等于數(shù)字 0,函數(shù)的終止條件判斷不通過(guò)。
所以程序進(jìn)入遞歸模式,再次調(diào)用自己。在后續(xù)進(jìn)行求余預(yù)算的時(shí)候,Lua 的 “ 智慧 ” 又突然起到了作用。Lua 一拍腦袋,咋會(huì)有人把字符 ‘ 0 ’ 拿來(lái)做計(jì)算啊,肯定是想把這個(gè)參數(shù)當(dāng)數(shù)字用。
于是發(fā)生了強(qiáng)制類(lèi)型轉(zhuǎn)換。
所以咱們小學(xué)數(shù)學(xué)都會(huì)學(xué)到的。。。把 0 當(dāng)除數(shù)的事情就發(fā)生了。這要是古老的大哥 C 語(yǔ)言來(lái)干這活,可能直接就給一個(gè) Floating point exception 報(bào)錯(cuò)了。但是 Lua 不一樣,作為一個(gè)新時(shí)代的 “ 智慧 ” 的語(yǔ)言,它會(huì)優(yōu)雅的返回一個(gè) nan(Not A Numbewr)。
程序,繼續(xù)運(yùn)行。更要命的是,nan 也不會(huì)等于0。。。程序的終止條件無(wú)法實(shí)現(xiàn)。這樣跑幾個(gè)循環(huán)之后,原本用來(lái)計(jì)算 a 和 b 的最大公約數(shù)的函數(shù) _gcd(a,b) 就變成了一個(gè)停不下來(lái)的函數(shù) _gcd(nan,nan)。
在停不下來(lái)的路上根本停不下來(lái),直接把 CPU 資源給吃滿了。
太聰明也不是一件好事啊。。。
就這樣,被占滿的 CPU 一口氣把別的業(yè)務(wù)也帶崩了。還得前面提到的在家的 B 站程序員沒(méi)法在家通過(guò) VPN 來(lái)?yè)尵染W(wǎng)絡(luò)么?沒(méi)錯(cuò),他們登錄內(nèi)網(wǎng)的時(shí)候,其中有部分服務(wù)也需要通過(guò)內(nèi)網(wǎng)來(lái)處理。。。
屬于是把鑰匙斷鎖眼里,也是崩的理所當(dāng)然了。崩完之后:最后,如果差友們對(duì)相關(guān)技術(shù)細(xì)節(jié)更感興趣的話,世超建議你看看 B 站發(fā)布的這篇2021.07.13 我們是這樣崩的除了對(duì)事故的起承轉(zhuǎn)合,還對(duì)未來(lái)技術(shù)的更進(jìn)與反思都做了更加專業(yè),全面的總結(jié)。
講道理,這樣的機(jī)會(huì)其實(shí)挺難得的。每年崩了的應(yīng)用何其多,但是愿意發(fā)出來(lái)給同行學(xué)習(xí),給普羅大眾看個(gè)樂(lè)子的寥寥無(wú)幾。
向上滑動(dòng)▼
B 站這次愿意分享,直面自己的 “ 傷疤 ” 。也讓我們看到了互聯(lián)網(wǎng)運(yùn)維上最真實(shí)的一面。這些經(jīng)驗(yàn),可不會(huì)寫(xiě)在任何教科書(shū)上。哦對(duì),這篇文章發(fā)出來(lái)的晚上,B 站其實(shí)又偷偷小崩了一次。。。
不知道是不是團(tuán)隊(duì)好好總結(jié)了去年經(jīng)驗(yàn)的緣故。這回還沒(méi)等大部分人反應(yīng)過(guò)來(lái)。。。B 站已經(jīng)把問(wèn)題給解決了。
關(guān)鍵詞: B站自曝去年服務(wù)器大崩潰原因 就因?yàn)檫@
網(wǎng)站首頁(yè) |網(wǎng)站簡(jiǎn)介 | 關(guān)于我們 | 廣告業(yè)務(wù) | 投稿信箱
Copyright © 2000-2020 www.hngelin.com All Rights Reserved.
中國(guó)網(wǎng)絡(luò)消費(fèi)網(wǎng) 版權(quán)所有 未經(jīng)書(shū)面授權(quán) 不得復(fù)制或建立鏡像
聯(lián)系郵箱:920 891 263@qq.com
垣曲县| 斗六市| 宣汉县| 福泉市| 东台市| 南安市| 伊宁县| 友谊县| 兴文县| 思茅市| 西青区| 达孜县| 孝昌县| 吴江市| 康马县| 彰化市| 耿马| 大港区| 克拉玛依市| 灵璧县| 松阳县| 靖西县| 泰安市| 台安县| 佛学| 扶风县| 永康市| 石河子市| 梁山县| 皮山县| 夏邑县| 吉林省| 历史| 平塘县| 天气| 乌拉特后旗| 杂多县| 萝北县| 高淳县| 社旗县| 凤阳县|