不知道大家还记不记得去年B站(哔哩哔哩)崩溃的那场严重事故,不,我记得还引起热议当时全网讨论。一年多过去了,今天看到前两天B站在公众号上发的测评报告。2021.07.13本文从至暗时刻、初始原因定位、故障止损、根本原因定位、原因解释、问题分析、优化改进、总结八个方面再现了事故发生及处理的全过程。不知道大家看过没有,我看了全文,看完还挺尴尬的。最终原因竟然是字符串类型数字参数0导致的死循环。不过文章本身的写法还是很专业和严谨的。对于我们技术类的同学来说,嗯,也是一次难得的学习机会。不过看到文中最后一段代码,还是忍不住多说了几句。一个求最大公约数的GCD函数,其实是导致B站崩溃的罪魁祸首。因为下面的代码对我来说太多了。太熟悉了,在学校参加过编程竞赛的同学应该都不会陌生。看到上面的报告,第一感觉就是没有做好类型转换导致的死循环,是弱类型设计的一个坑。如果被零除抛出异常而不是变成NaN,应该很快定位到问题。另外,从这份官方报告中,我看到多处提到了多活、容灾、分布式这些词。远程多活是分布式系统保证架构稳定性的常用解决方案。毕竟这么大的公司,系统架构肯定离不开分布式。下面我们就来看看,分布式系统都有哪些技术栈?记得我在左耳鼠大叔的专栏《左耳听风》里写过分布式架构。我将在这里与您分享一些内部摘录。构建分布式系统的目的是增加系统容量,提高系统可用性,转化为技术方面,即完成以下两件事。大流量处理。通过集群技术将大规模并发请求的负载分散到不同的机器上。关键业务保护。提高后台服务的可用性。说白了就是做两件事。一是提高整体架构的吞吐量,服务更多的并发和流量,二是提高系统的稳定性,让系统的可用性更高。为了提高架构的性能,让我们看一下提高系统性能的常用技术。缓存系统。添加缓存系统可以有效提高系统的访问能力。比如从前端浏览器,到网络,再到后端服务,底层的数据库、文件系统、硬盘、CPU都有缓存,这是提升快速访问能力最有效的手段。对于分布式系统下的缓存系统,需要的是缓存集群。比如用一个Proxy做缓存分片和路由。负载均衡系统。负载均衡系统是横向扩展的关键技术。它可以使用多台机器来共享部分流量请求。异步调用。异步系统主要是通过消息队列对请求进行排队,使前端请求的峰值能够被“拉平”,所谓削峰填谷。后端以它可以处理的速度处理请求。这样可以提高系统的吞吐量,但会影响实时性。同时也会引入消息丢失的问题,所以必须持久化消息,这会造成节点“有状态”,从而增加服务调度的难度。数据分区和数据镜像。数据分区就是将数据按照一定的方式(比如按地理位置)划分到多个区域,不同的数据区域共享不同区域的流量。这就需要数据路由的中间件,而数据镜像就是把一个数据库镜像成同一份数据的多份,这样就不需要数据路由的中间件了。可以在任意节点上读写,数据会在内部同步。然而,数据镜像最大的问题是数据的一致性。提高架构的稳定性接下来,让我们看一下提高系统稳定性的一些常用技巧。服务拆分。服务拆分主要有两个目的:一是隔离故障,二是复用服务模块。但是服务拆分后,会引入服务调用之间的依赖问题。服务冗余。服务冗余是为了消除单点故障,支持服务的弹性伸缩和故障迁移。然而,对于一些有状态服务,这些有状态服务的冗余带来了更高的复杂性。其中之一是在进行自动伸缩时,需要考虑数据复制或重新分片,迁移时必须将数据迁移到其他机器上。限流降级。当系统实在承受不住压力时,只能通过限流或功能降级等方式停止部分服务或拒绝部分用户,以保证整个架构不会挂掉。这些技术是保护措施。高可用性架构。一般来说,高可用架构是从冗余架构的角度来保证可用性的。例如,多租户隔离、多活灾难恢复或可以复制数据以保持一致性的集群。简而言之,就是避免单点故障。高可用运维。高可用运维是指DevOps中的CI/CD(持续集成/持续部署)。一个好的运维应该是一个非常顺畅的软件发布流水线,有足够的自动化测试,也可以做相应的灰度发布和线上系统的自动控制。通过这种方式,可以最大限度地减少“计划内”或“计划外”停机事件的持续时间。上述这些技术是非常技术性的,需要投入大量的时间和精力。就像不想当将军??的军人不是好军人一样,不想当架构师的程序员也不是好程序员,哈哈,路漫漫其修远兮,加油吧。
