7行代码让B站崩溃3小时

如何让指定 Windows 程序崩溃 在不修改任何代码的前提下,做到让指定程序崩溃 阅读详情
鱼羊 丰色 发自 凹非寺
量子位 | 公众号 QbitAI

一个小小字符“0”,竟引得B站全面崩溃。

e5634c5d87aa00e40e48ef1be1b6310c.jpeg

不知你是否还记得那一夜,B站“大楼停电”、“服务器爆炸”、“程序员删库跑路”的彻夜狂欢。(手动狗头)

时隔一年,背后“真凶”现在终于被阿B披露出来——

a1bd61d213c90ff1468084aeb9d06c8a.png

没想到吧,就是这么简单几行代码,直接干趴B站两三个小时,搞得B站程序员彻夜无眠头发狂掉。

你可能会问,这不就是个普普通通用来求最大公约数的函数吗,怎么就有如此大的威力?

背后一桩桩一件件,归根结底其实就一句话:0,它真的不兴除啊。

63aaeed332d5bf914f51733bfb05e30d.png

具体详情,咱们还是一起来看看“事故报告”。

字符串“0”引发的“血案”

先来说道说道引发惨案的根本原因,也就是开头贴出的这个gcd函数。

学过一点编程知识的小伙伴应该都知道,这是一种用辗转相除法来计算最大公约数的递归函数。

跟我们手算最大公约数的方法不同,这个算法是酱婶的:

举个简单的例子,a=24,b=18,求a和b的最大公约数;

a除以b,得到的余数是6,那么就让a=18,b=6,然后接着往下算;

18除以6,这回余数是0,那么6也就是24和18的最大公约数了。

也就是说,a和b反复相除取余数,直到b=0,函数中:

if b==0 then return a end

这个判断语句生效,结果就算出来了。

基于这样的数学原理,我们再来看这段代码,似乎没什么问题:

418cd8a113c89821cff2b517cd1d4b95.png

但如果输入的b是个字符串“0”呢?

B站的技术解析文章中提到,这段出事的代码是用Lua写的。Lua具有这么几个特点:

  • 这是一种动态类型语言,常用习惯里变量不需要定义类型,直接给变量赋值就行。

  • Lua在对一个数字字符串进行算术操作时,会尝试将这个数字字符串转成一个数字。

  • 在Lua语言中,数学运算n%0的结果是nan(Not A Number)。

我们来模拟一下这个过程:

1、当b是一个字符串“0”时,由于这个gcd函数没有对其进行类型校验,因此在碰上判定语句时,“0”不等于0,代码中“return _gcd(b, a%b)”触发,返回_gcd(“0”, nan)。

2、_gcd(“0”, nan)再次被执行,于是返回值变成了_gcd(nan, nan)。

这下就完犊子了,判定语句中b=0的条件永远没法达到,于是,死循环出现了。

也就是说,这个程序开始疯狂地原地转圈,并且为了一个永远得不到的结果,把CPU占了个100%,别的用户请求自然就处理不了了。

62cf6a7fb03ff4ebfdc3e5268dd3866f.png

那么问题来了,这个“0”它到底是怎么进去的呢?

官方说法是:

在某种发布模式中,应用的实例权重会短暂地调整为0,此时注册中心返回给SLB(负载均衡)的权重是字符串类型的“0”。此发布环境只有生产环境会用到,同时使用的频率极低,在SLB前期灰度过程中未触发此问题。

SLB在balance_by_lua阶段,会将共享内存中保存的服务IP、Port、Weight作为参数传给lua-resty-balancer模块用于选择upstream server,在节点weight=“0”时,balancer模块中的_gcd函数收到的入参b可能为“0”。

bug是如何定位的

以“事后诸葛亮”的视角来看,这个引发B站全面崩溃的根本原因多少有点让人直呼“就这”。

但从当事程序员的视角来看,事情确实没有辣么简单。

当天晚上22:52分——大部分程序员才刚下班或者还没下班的节骨眼(doge),B站运维收到服务不可用的报警,第一时间怀疑机房、网络、四层LB、七层SLB等基础设施出现问题。

然后立马和相关技术人员拉了个紧急语音会议开始处理。

5分钟后,运维发现承载全部在线业务的主机房七层SLB的CPU占用率达到了100%,无法处理用户请求,排除其他设施后,锁定故障为该层。

(七层SLB是指基于URL等应用层信息的负载均衡。负载均衡通过算法把客户请求分配到服务器集群,从而减少服务器压力。)

万般紧急之时,小插曲还现了:远程在家的程序员登上VPN却没法进入内网,只好又去call了一遍内网负责人,走了个绿色通道才全部上线(因为其中一个域名是由故障的SLB代理的)。

ff3e5a10609936f97f19341c4811f101.png

此时已经过去了25分钟,抢修正式开始。

首先,运维先热重启了一遍SLB,未恢复;然后尝试拒绝用户流量冷重启SLB,CPU依然100%,还是未恢复。

接着,运维发现多活机房SLB请求大量超时,但CPU未过载,正准备重启多活机房SLB时,内部群反应主站服务已恢复,视频播放、推荐、评论、动态等功能已基本正常。

此时是23点23分,距离事故发生31分钟。

值得一提的是,这些功能恢复其实是事发之时被网友们吐槽的“高可用容灾架构”发挥了作用。

96b0f3109cd8cbb06faa8fc0ab540358.png

至于这道防线为啥一开始没发挥作用,里头可能还有你我一点锅。

简单来说,就是大家伙点不开B站就开始疯狂刷新,CDN流量回源重试 + 用户重试,直接让B站流量突增4倍以上,连接数突增100倍到千万级别,多活SLB就给整过载了。

5c7e36379b470868cdf73d73aa70626f.png

不过,并不是所有服务都搞了多活架构,至此事情并没完全解决。

接下来的半个小时里,大家做了很多操作,回滚了最近两周左右上线的Lua代码,都没把剩余的服务恢复。

时间来到了12点,没有办法了,“先不管bug是怎么出来的,把服务全恢复了再说”。

简单+粗暴:运维直接耗时一小时重建了一组全新的SLB集群。

凌晨1点,新集群终于建好:

一边,有人负责陆续将直播、电商、漫画、支付等核心业务流量切换到新集群,恢复全部服务(凌晨1点50分全部搞定,暂时结束了崩了逼近3个小时的事故);

另一边,继续分析bug原因。

在他们用分析工具跑出一份详细的火焰图数据后,那个搞事的“0”才终于露出了一点端倪:

CPU热点明显集中在一个对lua-resty-balancer模块的调用中。而该模块的_gcd函数在某次执行后返回了一个预期外的值:NaN。

同时,他们也发现了触发诱因的条件:某个容器IP的weight=0。

他们怀疑是该函数触发了jit编译器的某个bug,运行出错陷入死循环导致SLB CPU 100%。

于是就全局关闭了jit编译,暂时规避了风险。一切都解决完后,已经快4点,大家终于暂时睡了个好觉。

第二天大家也没闲着,马不停蹄地在线下环境复现了bug后,发现并不是jit编译器的问题,而是服务的某种特殊发布模式会出现容器实例权重为0的情况,而这个0是个字符串形式。

正如前面所说,这个字符串“0”在动态语言Lua中的算术操作中,被转成了数字,走到了不该走的分支,造成了死循环,引发了b站此次前所未见的大崩溃事件。

递归的锅还是弱类型语言的锅?

不少网友都还对这次事故记忆犹新,有回想起自己就是以为手机不行换电脑也不行的,也有人还记得当时5分钟后此事就上了热搜。

大家都很诧异,就这么一个简单的死循环就能造成如此大的网站崩服。

不过,有人指出,死循环不罕见,罕见的是在SLB层、在分发过程出问题,它还不像在后台出问题很快能重启解决。

32ad94091dd96bb3ee50bd63229ed615.png

为了避免这种情况发生, 有人认为要慎用递归,硬要用还是设置一个计数器,达到一个业务不太可能达到的值后直接return掉。

还有人认为这不怪递归,主要还是弱类型语言的锅。

以此还导致了“诡计多端的‘0’”这一打趣的说法。

738d663900b2a3942c201c8edc2a3952.png

另外,由于事故实在是耽误了太久、太多事儿,当时B站给所有用户补了一天大会员。

有人就在此算了一笔账,称就是这7行代码,让b站老板一下亏了大约1,5750,0000元。(手动狗头)

998fb18794af0130b78859ffdec17dae.png

对于这个bug,你有什么想吐槽的?

参考链接:

[1]《2021.07.13 我们是这样崩的》by 哔哩哔哩技术
https://mp.weixin.qq.com/s/nGtC5lBX_Iaj57HIdXq3Qg

本月上榜的名单

我们每个月月底都会给大家送书(累计送出423多本),常来留言混脸熟的都会有机会!这次送出的是"AI相关的"书籍 ,非常值得一读,下面是上榜的名单。

614b4023d9da96fa2481a9221e432628.jpeg

2620f21e8d80e74700185e2fc8457092.jpeg

恭喜几位常来留言上榜的小伙伴,获得上面的书籍,尽快跟小助手联系(公众号后台输入:小助手),提供的你的快递信息。没有上榜的不要急,可以找小助手联系,咨询其他福利机会。

c4b40ff2533baed0bb4a419d64aed372.gif

推荐阅读:
入门: 最全的零基础学Python的问题  | 零基础学了8个月的Python  | 实战项目 |学Python就是这条捷径
干货:爬取豆瓣短评,电影《后来的我们》 | 38年NBA最佳球员分析 |   从万众期待到口碑扑街!唐探3令人失望  | 笑看新倚天屠龙记 | 灯谜答题王 |用Python做个海量小姐姐素描图 |碟中谍这么火,我用机器学习做个迷你推荐系统电影
趣味:弹球游戏  | 九宫格  | 漂亮的花 | 两百行Python《天天酷跑》游戏!
AI: 会做诗的机器人 | 给图片上色 | 预测收入 | 碟中谍这么火,我用机器学习做个迷你推荐系统电影
小工具: Pdf转Word,轻松搞定表格和水印! | 一键把html网页保存为pdf!|  再见PDF提取收费! | 用90行代码打造最强PDF转换器,word、PPT、excel、markdown、html一键转换 | 制作一款钉钉低价机票提示器! |60行代码做了一个语音壁纸切换器天天看小姐姐!|
一线大厂面试题-从B 站崩溃的故障排查和恢复过程中学到什么 2021 年 7 月 13 日晚上 22:52 ,B 站崩了。整个事件的罪魁祸首竟然只是,这么短短 的几行代码;回到 B 站崩溃那天 ,仅不到半个小时 ,这个消息就冲上了微博的热搜头条。从 B 站出来的用户甚至带崩了 A 站、豆瓣、知乎等多个网站。有网友调侃说, B 站服务器一蹦 ,紧张加班的除了 B 站的程序员 ,同时让 A 站知乎、豆瓣、微博的程序员默默打开了电脑。B 站崩溃的背后 ,背后的根本原因到底是什么呢?在这个事故发生后 ,公司内部必然要做的几件事情。 阅读详情

相关推荐

STM32F4三重ADC+DMA双缓冲实战:用CubeMX搞定同步采样,告别数据覆盖烦恼

本文详细介绍了STM32F4三重ADC与DMA双缓冲技术的实战应用,通过CubeMX配置实现同步采样,解决数据覆盖问题。内容涵盖硬件架构解析、CubeMX工程配置、双缓冲实现技巧及调试优化方法,适用于电机控制、电力监测等需要高精度多通道信号采集的场景。

weixin_30627341的博客 358

让站长崩溃的骚操作,你中过招吗?

那些让站长们抓狂的瞬间!许多站长在运营网站时都会遇到一个尴尬的问题:业务受到了黑客、黑产影响,却没有专人来维护网站的安全!建站时前端页面干净漂亮,但后端没有设置检测过滤和检测SQL语句,被一个SQL注入导出了数据库中所有用户的数据...莫名其妙服务器内存满了,原来是使用了"root"这样的用户名或弱口令,被爆破登录到服务器植入了挖矿程序,结果干扰了正常业务运行,发现时已经好几天没订单了...网站上...

DNSPod 370

Scratch 3.0角色控制避坑指南:为什么你的键盘移动总卡顿?

本文深入剖析了Scratch 3.0中角色移动卡顿的根本原因,指出依赖`当按下`事件积木的局限性。通过对比分析,推荐采用`重复执行`结合`如果<键被按下?>`的循环控制方案,并引入速度变量模拟惯性,从而实现流畅、实时的键盘控制优化,显著提升游戏操作体验。

dd012的博客 1016

一个不兼容的 JS 方法,让你的网站发生崩溃

在开发前台系统的过程中,遇到了一个很奇怪的问题:PC 端的请求都很正常,移动端浏览器的请求却全部失败,后来发现这是因为请求参数发生了丢失现象。 本文来源:魚立说。本文链接:https://www.yulisay.com/d/kobpr.html,支持微信浏览器打开。 更多精彩文章,请移步 魚立说个人网站 翻看。欢迎欣赏,吐槽不足之处。 本文将围绕 URL 查询字符串的序列化方法 URLSearchParams 展开内容,最终得出的结论是:在做兼容多端网站开发时,需要谨慎使用 URLSearchParams

qq__________qq的博客 1144

2023东华大学机试OJ进阶版1-81题

先排序。每次找两个最小的数,把其中一个置为两数之和,并累加这个和值,另一个数置为-1,然后再排序,重复操作,直到只剩下一个数。105。

m0_49263811的博客 2798

QOpenGL入门教程(二)—— 第一个QOpenGLWidget程序

终于到了实际操作的环节了,这一章我们要做的是: 创建OpenGL窗口 创建并编写着色器程序 为着色器程序装配顶点数据 启动渲染管线进行绘图 第一步:创建新项目 首先,我们使用Qt创建一个常规的QWidget项目,建议不要勾选ui设计器(个人习惯,笔者不太习惯于使用ui来设计) 第二步:创建QOpenGLWidget并实现三个虚函数 QOpenGLWidget Qt5.4之前,Qt可以通过一个QGLWidget类来创建OpenGL窗口,但由于opengl的发展,在5.4版本的时候,Qt提供

ItaLink 1万+

可以让浏览器崩溃的12行代码

起因 今天刷推特的时候发现Cyber Security@cyber__sec的推文让人眼前一亮: Crash firefox, chrome, safari browsers, and also restart iphone using this javascript code. #dos #0day #exploit //使用下面这段JavaScript代码能让firefox,chrome,

wackycrazy的专栏 7665

AIGC游戏本地化:用AI实现多语言自动翻译

游戏本地化是游戏全球化战略的关键环节,传统人工翻译方式成本高、周期长。本文旨在探讨如何利用AIGC技术实现高效、准确、低成本的游戏多语言自动翻译解决方案。我们将覆盖从文本翻译到语音合成的完整本地化流程,重点关注AI技术在游戏特定语境下的应用优化。文章首先介绍游戏本地化的核心挑战和AI解决方案,然后深入讲解关键技术原理,接着通过实战项目演示具体实现,最后讨论应用场景和未来趋势。AIGC:人工智能生成内容,指利用AI技术自动生成文本、图像、音频等内容本地化(Localization)

AI 领航者的博客 1339

7 行代码搞崩溃 B 站,原因令人唏嘘

△点击上方“Python猫”关注 ,回复“1”领取电子书作者:豌豆花下猫来源:Python猫前不久,哔哩哔哩(一般常称为 B 站)发布了一篇文章《2021.07.13 我们是这样崩的》,详细回顾了他们在 2021.07.13 晚上全站崩溃约 3 小时的至暗时刻,以及万分紧张的故障定位与恢复过程。那篇文章将定位过程、问题分析、优化改进等方面写得很详细,在我印象中,国内互联网...

Python猫 2万+

《无线传感网络 matlab》:从入门到实践

这就是如何使用Matlab建立一个简单的无线传感网络并进行仿真的方法。当然,这只是一个入门级的示例,真正的无线传感网络可能会更加复杂和庞大。首先,我们需要创建一个无线传感网络的基础结构。接下来,我们需要定义一个数据包的格式,以便节点之间可以交换信息。无线传感网络是一种由无线传感器节点组成的、自组织的网络。现在,我们可以开始编写节点代码了。我们将使用Matlab提供的工具箱来构建一个简单的无线传感网络,并对其进行仿真和分析。现在,我们可以将这个节点复制9次,以创建一个包含10个节点的无线传感网络。

NoerrorCode的博客 297

微软商店报错“此产品当前不可用”?终极修复指南

微软商店报错“此产品当前不可用”?终极修复指南

安德洛夫 3816

7行代码让B站崩溃3小时,竟因“一个诡计多端的0”

鱼羊 丰色 发自 凹非寺量子位 | 公众号 QbitAI一个小小字符“0”,竟引得B站全面崩溃。不知你是否还记得那一夜,B站“大楼停电”、“服务器爆炸”、“程序员删库跑路”的彻夜狂欢。(手动狗头)时隔一年,背后“真凶”现在终于被阿B披露出来——没想到吧,就是这么简单几行代码,直接干趴B站两三个小时,搞得B站程序员彻夜无眠头发狂掉。你可能会问,这不就是个普普通通用来求最大公...

量子位 1万+

【30天从零玩转AI应用开发】第16篇:智能体Agent入门——ReAct框架原理+首个会思考、会动手的AI实战

摘要: 本文介绍了AI智能体(Agent)的核心概念及其与普通大模型(LLM)的区别。通过ReAct(Reason+Act)框架,智能体实现了自主思考、调用工具和分步执行的能力。文章详细讲解了LangChain Agent的四大组件,并推荐新手使用ZERO_SHOT_REACT_DESCRIPTION类型。最后提供了一个完整的智能体实战代码示例,该智能体具备数学计算和天气查询功能,能够自主选择工具完成任务,展示了AI从”被动回答“到”主动行动“的关键进化。

在上海谋生的软件喵记录喵生 626

7行代码让B站崩溃3小时!

点击下方卡片,关注“CVer”公众号AI/CV重磅干货,第一时间送达点击进入—>CV微信技术交流群鱼羊 丰色 发自 凹非寺转载自:量子位(QbitAI)一个小小字符“0”,竟引得B站全面崩溃。不知你是否还记得那一夜,B站“大楼停电”、“服务器爆炸”、“程序员删库跑路”的彻夜狂欢。(手动狗头)时隔一年,背后“真凶”现在终于被阿B披露出来——没想到吧,就是这么简单几...

阿木寺的博客 426

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

B站 服务崩溃问题浅析2021/7/13日晚

14日凌晨,B站发布消息称: 昨晚,B站的部分服务器机房发生故障,造成无法访问。技术团队随即进行了问题排查和修复,现在服务已经陆续恢复正常。耽误大家看视频了,对不起! 已知: Bilibili,Acfun,豆瓣都出现崩溃404. 豆瓣和Acfun很快恢复,Bilibili大约用了一个小时让用户能够正常访问。 Bilibili直播是可以正常观看的,朋友看吃鸡直播没有受到影响。 B站高可用用架构实践 - 云+社区 - 腾讯云 (tencent.com) 根据上面文章可知,Bilibili的LB(负载均衡器)是

knight7765的博客 1万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

从 B 站崩溃的故障排查和恢复过程中学到什么?

大家发现没有,遇到生产事故的时候,在不清楚具体问题的情况下,优先重启相关服务节点来达到故障止损是效率最高的手段,因此 B 站的运维人员通过重启 SLB 以及多活节点后。而 Lua 又是弱类型语言,允许传入字符串“0”,这个时候 if 条件字符串 0 不等于数字 0,会执行_gcd 递归调用,其中在执行 a%b 的时候,用字符串和数字取模,得到一个 NaN 的结果。有网友调侃说,B 站服务器一蹦,紧张加班的除了 B 站的程序员,同时让 A 站\知乎、豆瓣、微博的程序员默默打开了电脑。

m0_52514893的博客 827

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

今天大佬告诉你B站崩溃的背后,b站高可用架构到底是怎么样的

面试准备 1、前面找一些小公司面试练练手,找找感觉,总结统计下不会的问题,然后再去找相关资料学习相关知识点,我这2个月大概面试有近10加公司吧,一共拿了3家offer,前面很多都没过,但是为后面拿更好的offer做准备 2、我是如何准备的呢 (1)首先就是简历,关注"三太子敖丙"里面有简历模板,参考下,我是参考了里面的模板修改了,然后在脉脉里找了字节的内推人员,他再帮我简历的一些问题给出了建议 (2)投简历,我用的是Boss直聘,大家也可以用智联招聘、脉脉内推等 (3)学习知识点,我下载了优快云,关注了一

weixin_54556126的博客 1527
上一篇: 干货!Python四大常用绘图库,深度解析!
下一篇: 太赞了!Python 开发神器Jupyter竟然还有可视化debug功能!
菜鸟学Python
博客等级 码龄9年 8087粉丝 571原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值