chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

字符串“0”引發(fā)的“血案”

算法與數(shù)據(jù)結(jié)構(gòu) ? 來(lái)源:AI新媒體量子位 ? 作者:AI新媒體量子位 ? 2022-08-03 11:26 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一個(gè)小小字符“0”,竟引得B站全面崩潰。

不知你是否還記得那一夜,B站“大樓停電”、“服務(wù)器爆炸”、“程序員刪庫(kù)跑路”的徹夜狂歡。(手動(dòng)狗頭)

時(shí)隔一年,背后“真兇”現(xiàn)在終于被阿B披露出來(lái)——

376e1b9e-12db-11ed-ba43-dac502259ad0.png

沒(méi)想到吧,就是這么簡(jiǎn)單幾行代碼,直接干趴B站兩三個(gè)小時(shí),搞得B站程序員徹夜無(wú)眠頭發(fā)狂掉。

你可能會(huì)問(wèn),這不就是個(gè)普普通通用來(lái)求最大公約數(shù)的函數(shù)嗎,怎么就有如此大的威力?

背后一樁樁一件件,歸根結(jié)底其實(shí)就一句話:0,它真的不興除啊。

具體詳情,咱們還是一起來(lái)看看“事故報(bào)告”。

字符串“0”引發(fā)的“血案”

先來(lái)說(shuō)道說(shuō)道引發(fā)慘案的根本原因,也就是開(kāi)頭貼出的這個(gè)gcd函數(shù)。

學(xué)過(guò)一點(diǎn)編程知識(shí)的小伙伴應(yīng)該都知道,這是一種用輾轉(zhuǎn)相除法來(lái)計(jì)算最大公約數(shù)的遞歸函數(shù)。

跟我們手算最大公約數(shù)的方法不同,這個(gè)算法是醬嬸的:

舉個(gè)簡(jiǎn)單的例子,a=24,b=18,求a和b的最大公約數(shù);

a除以b,得到的余數(shù)是6,那么就讓a=18,b=6,然后接著往下算;

18除以6,這回余數(shù)是0,那么6也就是24和18的最大公約數(shù)了。

也就是說(shuō),a和b反復(fù)相除取余數(shù),直到b=0,函數(shù)中:

if b==0 then return a end

這個(gè)判斷語(yǔ)句生效,結(jié)果就算出來(lái)了。

基于這樣的數(shù)學(xué)原理,我們?cè)賮?lái)看這段代碼,似乎沒(méi)什么問(wèn)題:

376e1b9e-12db-11ed-ba43-dac502259ad0.png

但如果輸入的b是個(gè)字符串“0”呢?

B站的技術(shù)解析文章中提到,這段出事的代碼是用Lua寫(xiě)的。Lua具有這么幾個(gè)特點(diǎn):

  • 這是一種動(dòng)態(tài)類型語(yǔ)言,常用習(xí)慣里變量不需要定義類型,直接給變量賦值就行。

  • Lua在對(duì)一個(gè)數(shù)字字符串進(jìn)行算術(shù)操作時(shí),會(huì)嘗試將這個(gè)數(shù)字字符串轉(zhuǎn)成一個(gè)數(shù)字。

  • 在Lua語(yǔ)言中,數(shù)學(xué)運(yùn)算n%0的結(jié)果是nan(Not A Number)。

我們來(lái)模擬一下這個(gè)過(guò)程:

1、當(dāng)b是一個(gè)字符串“0”時(shí),由于這個(gè)gcd函數(shù)沒(méi)有對(duì)其進(jìn)行類型校驗(yàn),因此在碰上判定語(yǔ)句時(shí),“0”不等于0,代碼中“return _gcd(b, a%b)”觸發(fā),返回_gcd(“0”, nan)。

2、_gcd(“0”, nan)再次被執(zhí)行,于是返回值變成了_gcd(nan, nan)。

這下就完?duì)僮恿?,判定語(yǔ)句中b=0的條件永遠(yuǎn)沒(méi)法達(dá)到,于是,死循環(huán)出現(xiàn)了。

也就是說(shuō),這個(gè)程序開(kāi)始瘋狂地原地轉(zhuǎn)圈,并且為了一個(gè)永遠(yuǎn)得不到的結(jié)果,把CPU占了個(gè)100%,別的用戶請(qǐng)求自然就處理不了了。

那么問(wèn)題來(lái)了,這個(gè)“0”它到底是怎么進(jìn)去的呢?

官方說(shuō)法是:

在某種發(fā)布模式中,應(yīng)用的實(shí)例權(quán)重會(huì)短暫地調(diào)整為0,此時(shí)注冊(cè)中心返回給SLB(負(fù)載均衡)的權(quán)重是字符串類型的“0”。此發(fā)布環(huán)境只有生產(chǎn)環(huán)境會(huì)用到,同時(shí)使用的頻率極低,在SLB前期灰度過(guò)程中未觸發(fā)此問(wèn)題。

SLB在balance_by_lua階段,會(huì)將共享內(nèi)存中保存的服務(wù)IP、Port、Weight作為參數(shù)傳給lua-resty-balancer模塊用于選擇upstream server,在節(jié)點(diǎn)weight=“0”時(shí),balancer模塊中的_gcd函數(shù)收到的入?yún)可能為“0”。

bug是如何定位的

以“事后諸葛亮”的視角來(lái)看,這個(gè)引發(fā)B站全面崩潰的根本原因多少有點(diǎn)讓人直呼“就這”。

但從當(dāng)事程序員的視角來(lái)看,事情確實(shí)沒(méi)有辣么簡(jiǎn)單。

當(dāng)天晚上22:52分——大部分程序員才剛下班或者還沒(méi)下班的節(jié)骨眼(doge),B站運(yùn)維收到服務(wù)不可用的報(bào)警,第一時(shí)間懷疑機(jī)房、網(wǎng)絡(luò)、四層LB、七層SLB等基礎(chǔ)設(shè)施出現(xiàn)問(wèn)題。

然后立馬和相關(guān)技術(shù)人員拉了個(gè)緊急語(yǔ)音會(huì)議開(kāi)始處理。

5分鐘后,運(yùn)維發(fā)現(xiàn)承載全部在線業(yè)務(wù)的主機(jī)房七層SLB的CPU占用率達(dá)到了100%,無(wú)法處理用戶請(qǐng)求,排除其他設(shè)施后,鎖定故障為該層。

(七層SLB是指基于URL等應(yīng)用層信息的負(fù)載均衡。負(fù)載均衡通過(guò)算法把客戶請(qǐng)求分配到服務(wù)器集群,從而減少服務(wù)器壓力。)

萬(wàn)般緊急之時(shí),小插曲還現(xiàn)了:遠(yuǎn)程在家的程序員登上VPN卻沒(méi)法進(jìn)入內(nèi)網(wǎng),只好又去call了一遍內(nèi)網(wǎng)負(fù)責(zé)人,走了個(gè)綠色通道才全部上線(因?yàn)槠渲幸粋€(gè)域名是由故障的SLB代理的)

37980cb0-12db-11ed-ba43-dac502259ad0.png

此時(shí)已經(jīng)過(guò)去了25分鐘,搶修正式開(kāi)始。

首先,運(yùn)維先熱重啟了一遍SLB,未恢復(fù);然后嘗試拒絕用戶流量冷重啟SLB,CPU依然100%,還是未恢復(fù)。

接著,運(yùn)維發(fā)現(xiàn)多活機(jī)房SLB請(qǐng)求大量超時(shí),但CPU未過(guò)載,正準(zhǔn)備重啟多活機(jī)房SLB時(shí),內(nèi)部群反應(yīng)主站服務(wù)已恢復(fù),視頻播放、推薦、評(píng)論、動(dòng)態(tài)等功能已基本正常。

此時(shí)是23點(diǎn)23分,距離事故發(fā)生31分鐘。

值得一提的是,這些功能恢復(fù)其實(shí)是事發(fā)之時(shí)被網(wǎng)友們吐槽的“高可用容災(zāi)架構(gòu)”發(fā)揮了作用。

37a6903c-12db-11ed-ba43-dac502259ad0.png

至于這道防線為啥一開(kāi)始沒(méi)發(fā)揮作用,里頭可能還有你我一點(diǎn)鍋。

簡(jiǎn)單來(lái)說(shuō),就是大家伙點(diǎn)不開(kāi)B站就開(kāi)始瘋狂刷新,CDN流量回源重試 + 用戶重試,直接讓B站流量突增4倍以上,連接數(shù)突增100倍到千萬(wàn)級(jí)別,多活SLB就給整過(guò)載了。

不過(guò),并不是所有服務(wù)都搞了多活架構(gòu),至此事情并沒(méi)完全解決。

接下來(lái)的半個(gè)小時(shí)里,大家做了很多操作,回滾了最近兩周左右上線的Lua代碼,都沒(méi)把剩余的服務(wù)恢復(fù)。

時(shí)間來(lái)到了12點(diǎn),沒(méi)有辦法了,“先不管bug是怎么出來(lái)的,把服務(wù)全恢復(fù)了再說(shuō)”。

簡(jiǎn)單+粗暴:運(yùn)維直接耗時(shí)一小時(shí)重建了一組全新的SLB集群。

凌晨1點(diǎn),新集群終于建好:

一邊,有人負(fù)責(zé)陸續(xù)將直播、電商、漫畫(huà)、支付等核心業(yè)務(wù)流量切換到新集群,恢復(fù)全部服務(wù)(凌晨1點(diǎn)50分全部搞定,暫時(shí)結(jié)束了崩了逼近3個(gè)小時(shí)的事故);

另一邊,繼續(xù)分析bug原因。

在他們用分析工具跑出一份詳細(xì)的火焰圖數(shù)據(jù)后,那個(gè)搞事的“0”才終于露出了一點(diǎn)端倪:

CPU熱點(diǎn)明顯集中在一個(gè)對(duì)lua-resty-balancer模塊的調(diào)用中。而該模塊的_gcd函數(shù)在某次執(zhí)行后返回了一個(gè)預(yù)期外的值:NaN。

同時(shí),他們也發(fā)現(xiàn)了觸發(fā)誘因的條件:某個(gè)容器IP的weight=0。

他們懷疑是該函數(shù)觸發(fā)了jit編譯器的某個(gè)bug,運(yùn)行出錯(cuò)陷入死循環(huán)導(dǎo)致SLB CPU 100%。

于是就全局關(guān)閉了jit編譯,暫時(shí)規(guī)避了風(fēng)險(xiǎn)。一切都解決完后,已經(jīng)快4點(diǎn),大家終于暫時(shí)睡了個(gè)好覺(jué)。

第二天大家也沒(méi)閑著,馬不停蹄地在線下環(huán)境復(fù)現(xiàn)了bug后,發(fā)現(xiàn)并不是jit編譯器的問(wèn)題,而是服務(wù)的某種特殊發(fā)布模式會(huì)出現(xiàn)容器實(shí)例權(quán)重為0的情況,而這個(gè)0是個(gè)字符串形式。

正如前面所說(shuō),這個(gè)字符串“0”在動(dòng)態(tài)語(yǔ)言Lua中的算術(shù)操作中,被轉(zhuǎn)成了數(shù)字,走到了不該走的分支,造成了死循環(huán),引發(fā)了b站此次前所未見(jiàn)的大崩潰事件。

遞歸的鍋還是弱類型語(yǔ)言的鍋?

不少網(wǎng)友都還對(duì)這次事故記憶猶新,有回想起自己就是以為手機(jī)不行換電腦也不行的,也有人還記得當(dāng)時(shí)5分鐘后此事就上了熱搜。

大家都很詫異,就這么一個(gè)簡(jiǎn)單的死循環(huán)就能造成如此大的網(wǎng)站崩服。

不過(guò),有人指出,死循環(huán)不罕見(jiàn),罕見(jiàn)的是在SLB層、在分發(fā)過(guò)程出問(wèn)題,它還不像在后臺(tái)出問(wèn)題很快能重啟解決。

37b0daa6-12db-11ed-ba43-dac502259ad0.png

為了避免這種情況發(fā)生, 有人認(rèn)為要慎用遞歸,硬要用還是設(shè)置一個(gè)計(jì)數(shù)器,達(dá)到一個(gè)業(yè)務(wù)不太可能達(dá)到的值后直接return掉。

還有人認(rèn)為這不怪遞歸,主要還是弱類型語(yǔ)言的鍋。

以此還導(dǎo)致了“詭計(jì)多端的‘0’”這一打趣的說(shuō)法。

37bc89e6-12db-11ed-ba43-dac502259ad0.png

另外,由于事故實(shí)在是耽誤了太久、太多事兒,當(dāng)時(shí)B站給所有用戶補(bǔ)了一天大會(huì)員。

有人就在此算了一筆賬,稱就是這7行代碼,讓b站老板一下虧了大約1,5750,0000元。(手動(dòng)狗頭)

37caf58a-12db-11ed-ba43-dac502259ad0.png

對(duì)于這個(gè)bug,你有什么想吐槽的?

參考鏈接:

[1]《2021.07.13 我們是這樣崩的》by 嗶哩嗶哩技術(shù)
https://mp.weixin.qq.com/s/nGtC5lBX_Iaj57HIdXq3Q

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 字符串
    +關(guān)注

    關(guān)注

    1

    文章

    596

    瀏覽量

    23129
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4413

    瀏覽量

    67260
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4958

    瀏覽量

    73579

原文標(biāo)題:7行代碼讓B站崩潰3小時(shí)

文章出處:【微信號(hào):TheAlgorithm,微信公眾號(hào):算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    選錯(cuò)PCB基材引發(fā)血案

    )、 表面處理 、 字符 組成。 PCB電路板的主要材料是覆銅板, 而覆銅板(敷銅板)是由銅箔(成本占比30%-40%)、玻璃布(基板,成本占比20%-25%)、樹(shù)脂(粘合劑,成本占比25%-30
    的頭像 發(fā)表于 01-29 09:06 ?77次閱讀
    選錯(cuò)PCB基材<b class='flag-5'>引發(fā)</b>的<b class='flag-5'>血案</b>

    字符串控件與靜態(tài)字符串控件中預(yù)覽字符顯示亂碼,如何修改顯示正常?

    字符串控件與靜態(tài)字符串控件中預(yù)覽字符顯示亂碼,如何修改顯示正常?
    發(fā)表于 01-20 17:17

    字符串,數(shù)字控件如何控制背景顏色和前景字體顏色?

    字符串,數(shù)字控件如何控制背景顏色和前景字體顏色?
    發(fā)表于 01-20 15:12

    Linux下怎么讓中文字符串按照拼音排序?

    求教 Linux 下怎么讓中文字符串按照拼音排序?
    發(fā)表于 01-06 07:40

    字符串關(guān)聯(lián)數(shù)字變量如何使用?我們的地址都是16位數(shù)據(jù),可以使用16位數(shù)字變量顯示字符串嗎?

    字符串關(guān)聯(lián)數(shù)字變量如何使用?我們的地址都是16位數(shù)據(jù),可以使用16位數(shù)字變量顯示字符串嗎?
    發(fā)表于 12-15 08:24

    飛凌嵌入式ElfBoard-標(biāo)準(zhǔn)IO接口之格式化輸出

    ( const char *format, ... );3)參數(shù)format:表示C 字符串,包含了要打印的格式化數(shù)據(jù)。...:表示附加可變參數(shù),根據(jù)不同的 format 字符串,函數(shù)可能需要一系列的附加
    發(fā)表于 11-11 08:43

    如何使用 NuMaker 板和 Mbed OS 上的連接字符串連接到 Azure IoT?

    使用 NuMaker 板和 Mbed OS 上的連接字符串連接到 Azure IoT
    發(fā)表于 09-04 07:46

    非對(duì)稱密鑰生成和轉(zhuǎn)換規(guī)格詳解

    當(dāng)前章節(jié)將說(shuō)明系統(tǒng)目前支持的算法及其對(duì)應(yīng)的規(guī)格。密鑰生成有兩種指定規(guī)格的方式,分別是: 字符串參數(shù):以字符串的形式描述開(kāi)發(fā)者需要生成的密鑰規(guī)格。 密鑰參數(shù):使用密鑰的詳細(xì)密碼學(xué)信息,構(gòu)造密鑰對(duì)象
    發(fā)表于 09-01 07:50

    LM3466 多 LED 電流平衡器技術(shù)手冊(cè)

    到電源的數(shù)或每個(gè) LED 的正向電壓 字符串。 如果任何 LED 燈在運(yùn)行過(guò)程中打開(kāi),LM3466 會(huì)自動(dòng)平衡通過(guò)所有剩余活動(dòng) LED 燈的電源電流。 如 因此,即使一些 LED
    的頭像 發(fā)表于 08-29 14:27 ?976次閱讀
    LM3466 多<b class='flag-5'>串</b> LED 電流平衡器技術(shù)手冊(cè)

    labview如何生成一個(gè)帶字符串返回的dll

    labview如何生成一個(gè)dll,如下圖,要求一個(gè)輸入,類型是字符串,返回類型也是字符串
    發(fā)表于 08-28 23:20

    在Python中字符串逆序有幾種方式,代碼是什么

    對(duì)于一個(gè)給定的字符串,逆序輸出,這個(gè)任務(wù)對(duì)于python來(lái)說(shuō)是一種很簡(jiǎn)單的操作,畢竟強(qiáng)大的列表和字符串處理的一些列函數(shù)足以應(yīng)付這些問(wèn)題 了,今天總結(jié)了一下python中對(duì)于字符串的逆序輸出的幾種常用
    的頭像 發(fā)表于 08-28 14:44 ?913次閱讀

    SQL 通用數(shù)據(jù)類型

    如何與存儲(chǔ)的數(shù)據(jù)進(jìn)行交互。 下面的表格列出了 SQL 中通用的數(shù)據(jù)類型: 數(shù)據(jù)類型 描述 CHARACTER(n) 字符/字符串。固定長(zhǎng)度 n。 VARCHAR(n) 或 CHARACTER VARYING(n) 字符/
    的頭像 發(fā)表于 08-18 09:46 ?677次閱讀

    為啥51單片機(jī)能搞,峰岹的就會(huì)報(bào)錯(cuò)呢?

    如圖圖1是stc系列單片機(jī)的代碼,發(fā)送字符串都可以,但是圖二峰岹的代碼發(fā)送字符串就不行,會(huì)報(bào)錯(cuò)
    發(fā)表于 07-09 13:39

    harmony-utils之StrUtil,字符串工具類

    harmony-utils之StrUtil,字符串工具類 harmony-utils 簡(jiǎn)介與說(shuō)明 [harmony-utils] 一款功能豐富且極易上手的HarmonyOS工具庫(kù),借助眾多實(shí)用工具類
    的頭像 發(fā)表于 07-03 11:32 ?493次閱讀

    STM32C031C6使用的是UART2通訊,通過(guò)printf()函數(shù)發(fā)送字符串時(shí),漢字錯(cuò)碼怎么解決?

    使用的是UART2通訊,通過(guò)printf()函數(shù)發(fā)送字符串時(shí),漢字錯(cuò)碼(見(jiàn)下圖),應(yīng)該是KEIL哪里沒(méi)有設(shè)置好的問(wèn)題。 啟用了UART2的中斷接收,可以接收到串口調(diào)試助手的數(shù)據(jù),但是緩存區(qū)的指針沒(méi)有歸零,下次接收時(shí)緩存區(qū)中的內(nèi)容接續(xù)(如下圖所示),不知道用什么命令來(lái)清除緩存區(qū)(即讓指針歸零)。
    發(fā)表于 03-07 12:30