不知道差友们还记不记得,去年的 7 月 13 日,B 站发生了一件大事。它毫无征兆的崩了。。。( 若是忘了的小同伴,可以看 这篇文章 )

至于为啥崩了,那时人人谁也心里没个底。不外吹起水来可是一套一套的,什么停电啊,起火啊,程序员 rm -rf /* 跑路啊。。。说的是个天马行空。
厥后呢,随着 B 站在破晓两点一顿修仙,把服务器问题给逐步解决,这件事情也算是告一段落了。
本以为这次 B 站崩了会和微博上无数崩了的网站一样,成为我们冲浪生涯中的一个笑谈,仅留下一个大会员给我们 “ 想念 ”。
没想到在今年的 7 月 13 日,B 站特意发了一篇文章,刨开心窝子来给我们讲了一讲,谁人晚上,到底发生了什么。

咱也看了一下这篇文章,好家伙,让整个 B 站溃逃的缘故原由,竟然只是一行代码没写好???借着这篇文章,世超准备带人人从 B 站的角度往返顾一下这件事情。放心,不会有生涩难明的名词,不会有犀利糊涂的黑话,保证小白也能看明了。 案情回溯: 意外,发生在 2021 年 7 月 13 日的 22 时 52 分。
认真搞定站点可靠性的工程师(SRE)和B站的客服都收到了大量网站打不开的报警。

而认真处置这些事故的同事已经下班了,立即准备在家里通过 VPN 来登录公司内网处置这些问题。
效果发现VPN 也崩了。。。压根进不去系统。最后,照样在公司的整了个 “ 绿色通道 ” 才乐成进去。你说这绿色通道不会是向日葵吧(一种远程桌面软件)
▼

而在绿色通道乐成买通,认真种种营业的团队就位之后,B 站也最先对问题举行剖析定位。出问题的模块也很显著,在线营业主机房的7层 SLB(负载平衡服务器,用来处置多用户,多营业的情形)的 CPU 跑满了 100%。
简朴来说,就是 CPU 被不知道那里来的刺客给占用光了算力,没法处置营业了。
系统未响应.exe ▼
B 站最最先的实验方式呢,和咱们平时手机电脑卡机后做的操作一样。
重启就完事了,要信托重启能解决 90% 的问题!

但很惋惜,B 站这次是谁人 10.5%。
说营业恢复了嘛,也没有,主机房重启后照样泛起了CPU 跑满 100%的问题。不外其余机房好起来了,虽然会卡,然则没泛起 CPU 跑满的问题。

有一部门做了多活的营业(多站点同时提供服务)最先逐步恢复。以是。。。重启不能完全解决问题,然则这个问题既然已往没泛起过。
那会不会是新加入的代码问题呢?随着时间在一分一秒的已往,借助剖析工具的辅助,问题被定位到了最近新上线的 Lua (一种编程语言,类似 Python,Java 这些) 函数上。
随后,B 站最先举行了一波波主要的回滚操作。

这一通事情弄下来,虽然似乎找到几个疑似出问题的部位,但服务器照样该挂挂,距离 “ 康复 ” 另有那么一些距离。
没设施,总得让营业先跑起来吧。于是团队最先兵分两路。一队继续坚持排盘问题,寻找缘故原由,另一队则是最先重修一个新的 SLB 服务。
在主要刺激的一小时后,新的 SLB 设置乐成,原本导向主站的流量也逐步的最先迁徙已往。

面试题问如厕习惯 涉事公司回应能看一个人基本情况:网友求公司名好避雷
面试题问如厕习惯 涉事公司回应能看一个人基本情况:网友求公司名好避雷
幸亏这次行了。
破晓两点,在溃逃了三小时之后,B 站的营业总算获得了恢复。 罪魁罪魁: 上面这些,就是谁人晚上 B 站发生的故事,虽然解决了外面问题,让营业恢复了。
可是最基本的缘故原由是啥呢?若是不找到根因,那早晚会二度暴雷。
认真排盘问题的同砚也没让人失望,在时间压力大大放缓之后,找出了真相。没有外星人,没有起火,没有断电,和网友们想象的截然差异。B 站这次崩的根因,仅仅是由于一个求最大条约数的函数没写好。。。

咱先盘一下这个 “ 万恶之源 ” 哈。
这是一个典型的 “ 自己挪用自己 ” 的递归函数。a b两数字辗转求余,直到 b 即是 0 的时刻函数终止。否则这个函数就会自己挪用自己,重新再跑一遍。
看上去似乎是一点点问题都没有,既明确了递归的终止条件(b = 0),也没有太多庞大的逻辑处置。然则既然事情能生长到这境界。。。那就说明是出大问题了。对编程有些领会的差友可能发现了纰谬:
你传进去的 0,是个什么 0?没错,在编程语言里,数字 0 和字符串 ‘ 0 ’ 并不算是一个器械。为了防止呆呆的盘算机语言把事情给搞混,像 C 语言,Java 这些静态语言都市要求我们在确立新变量的时刻声明这个变量的类型。
搞清晰它到底是整数,照样小数,或者是一个字符。然而 Lua 是个异常智慧的语言,它没有这个要求。穷苦的脏活累活让它自动来做就好了,Lua 会凭证程序的需求自动分配变量类型。
C语言示例:# 界说一个整型数据a,为它赋值1# 界说一个字符串数据b,为它赋值‘1’int a = 0;char a = ‘0’;Lua示例:–界说 a 为数字0,b为字符串‘0’a = 0b = ‘0’
以是,我们给参数 b 传进去的数值,是数字 0 呢,照样字符 ‘ 0 ’ ?一旦前面数据验证没把好关,在执行某个功效的时刻,把字符 ‘ 0 ’ 给传到了这个函数里。
地雷就被引爆了。字符串 ‘ 0 ’ 不会即是数字 0,函数的终止条件判断不通过。

以是程序进入递归模式,再次挪用自己。在后续举行求余预算的时刻,Lua 的 “ 智慧 ” 又突然起到了作用。Lua 一拍脑壳,咋会有人把字符 ‘ 0 ’ 拿来做盘算啊,一定是想把这个参数当数字用。

于是发生了强制类型转换。

以是咱们小学数学都市学到的。。。 把 0 当除数的事情就发生了。这要是古老的年迈 C 语言来干这活,可能直接就给一个 Floating point exception 报错了。然则 Lua 纷歧样,作为一个新时代的 “ 智慧 ” 的语言,它会优雅的返回一个 nan (Not A Numbewr)。
程序,继续运行。更要命的是,nan 也不会即是0。。。程序的终止条件无法实现。这样跑几个循环之后,原本用来盘算 a 和 b 的最大条约数的函数 _gcd(a,b) 就酿成了一个停不下来的函数 _gcd(nan,nan)。
在停不下来的路上基本停不下来,直接把 CPU 资源给吃满了。
太伶俐也不是一件好事啊。。。
就这样,被占满的 CPU 一口吻把其余营业也带崩了。还得前面提到的在家的 B 站程序员没法在家通过 VPN 来抢救网络么?没错,他们登录内网的时刻,其中有部门服务也需要通过内网来处置。。。

属于是把钥匙断锁眼里,也是崩的天经地义了。 崩完之后: 最后,若是差友们对相关手艺细节更感兴趣的话,世超建议你看看 B 站宣布的这篇2021.07.13 我们是这样崩的除了对事故的起承转合,还对未来手艺的更进与反思都做了加倍专业,周全的总结。
讲原理,这样的时机实在挺忧伤的。每年崩了的应用何其多,然则愿意发出来给偕行学习,给普罗民众看个乐子的寥若晨星。
向上滑动 ▼
B 站这次愿意分享,直面自己的 “ 伤疤 ” 。也让我们看到了互联网运维上最真实的一面。这些履历,可不会写在任何教科书上。哦对,这篇文章发出来的晚上,B 站实在又偷偷小崩了一次。。。
不知道是不是团队好好总结了去年履历的缘故。这回还没等大部门人反映过来。。。B 站已经把问题给解决了。

责任编辑:随心文章纠错
,
原创文章,作者:造梦软件,如若转载,请注明出处:https://www.zaomengapp.com/archives/45111.html