B站崩了、Facebook崩了,我们到底该怎么保证高可用
相信前一段时间的新闻大家都知道了,B站崩了三个半小时,Facebook全球崩了7个小时,那么作为工程师的我们到底应该怎么保证我们系统的稳定性和高可用呢?在了解以下思路和方案之前,我们先抛个砖,我们可以在两个层面保证高可用
- 开发设计层面
- 冗余:主备,负载均衡,failover
- 取舍:降级,限流,熔断,超时控制
- 运维层面
- 灰度发、A/B Test
- 故障演练
- 监控报警
- 异地多活
背景
以B站为例,我们来回顾一下B站宕机到恢复的时间线。
- 2021年7月13日 晚上11点,B站主页崩溃
App端页面无法加载数据
- 2021年7月13日 晚上23点30 分,B 站做了降级页面,将 404 页面跳转到了比较友好的异常页面
- 2021年7月13日 晚上23点35 主页可以加载出数据了,但是点击动态还是会报 502
点击某个视频,直接报 404。
- 2021年7月14日 凌晨2点之后 B 站开始逐渐恢复
从以上的时间线来看,B站在接收到宕机的消息之后的确在第一时间处理了,并进行了合理的降级。但是从晚上23点一直到第二天凌晨2点之后才逐步恢复,整个过程耗时两个半小时之后,给公司带来的影响可想而知。
定量分析系统高可用
说到定量分析可能很多人有点一头雾水,但是说到保证系统的三个9、四个9、五个9、六个9
,很多人一下就明白了。
来反观下 B 站故障了多久,2021-07-13 23:00 到 2021-07-14 02:00,系统逐渐恢复,如果按照年故障总时间来算的话:B 站故障超过 1 个小时了,只能算达到了三个九的标准。如果按照日故障时间来算,只能达到两个九的标准,也就是 99% 的高可用性,有点惨…
- 一个九和两个九
非常容易达到,一个正常的线上系统不会每天宕机 15 分钟吧,不然真用不下去了。
- 三个九和四个九
允许故障的时间很短,年故障时间是 1 小时到 8 小时,需要从架构设计、代码质量、运维体系、故障处理手册等入手,其中非常关键的一环是运维体系,如果线上出了问题,第一波收到异常通知的肯定是运维团队,根据问题的严重程度,会有不同的运维人员来处理,像 B 站这种大事故,就得运维负责人亲自上阵了。另外在紧急故障发生时,是否可以人工手段降级或者加开关,限制部分功能,也是需要考虑的。
- 五个九
年故障时间 5 分钟以内,这个相当短,即使有强大的运维团队每天值班也很难在收到异常报警后,5 分钟内快速恢复,所以只能用自动化运维来解决。也就是服务器自己来保证系统的容灾和自动恢复的能力。
- 六个九
这个标准相当苛刻了,年故障时间 32 秒。
针对不同的系统,其实对几个九也不相同。比如公司内部的员工系统,要求四个九就可以,如果是给全国用户使用,且使用人数很多,比如某宝、某东,那么就要求五个九以上了,但是即使是数一数二的电商系统,它里面也有非核心的业务,其实也可以放宽限制,四个九足以,这个就看各家系统的要求,都是成本、人力、重要程度的权衡考虑。
什么是高可用
高可用性(High Availability,HA)我们已经耳熟能详,指的是系统具备较高的无故障运行的能力
。简单来理解是指以减少服务中断时间为目的的服务器集群技术。它通过保护用户的业务程序对外不间断地提供服务,把因为软件,硬件,人为造成的故障对业务的影响降低到最小程度,总而言之就是保证公司业务7*24小时不宕机。
如何保证高可用
高可用的方案也是很常见:主备和故障转移、超时控制、限流、隔离、熔断、降级等。
熔断
断路保护。比如 A 服务调用 B 服务,由于网络问题或 B 服务宕机了或 B 服务的处理时间长,导致请求的时间超长,如果在一定时间内多次出现这种情况,就可以直接将 B 断路了(A 不再请求B)。而调用 B 服务的请求直接返回降级数据,不必等待 B 服务的执行。因此 B 服务的问题,不会级联影响到 A 服务。
常用的解决方案是Hystrix
限流
所谓限流就是对请求的流量进行控制, 只放行部分请求,使服务能够承担不超过自己能力的流量压力。常见限流算法有三种:时间窗口、漏桶算法、令牌桶算法。
- 漏桶算法
漏桶算法由流量容器、流量入口和出口组成。其中流量出口流速即为我们期望的限速值,比如 100 QPS。漏桶算法除了具备限流能力,还具备流量整型功能。下面我们通过一张图来了解漏桶算法。
如上图,流入漏桶流量的流速是不恒定的,经过漏桶限速后,流出流量的速度是恒定的。需要说明的是,漏桶的容量是有限的,一旦流入流量超出漏桶容量,这部分流量只能被丢弃了。
缺陷:面对突发流量的时候,采用的解决方式是缓存在漏桶中,这样流量的响应时间就会增长,这就与互联网业务低延迟的要求不符。
- 令牌桶算法
令牌桶和漏桶颇有几分相似,只不过令牌通里存放的是令牌。它的运行过程是这样的,一个令牌工厂按照设定值定期向令牌桶发放令牌。当令牌桶满了后,多出的令牌会被丢弃掉。每当一个请求到来时,该请求对应的线程会从令牌桶中取令牌。初期由于令牌桶中存放了很多个令牌,因此允许多个请求同时取令牌。当桶中没有令牌后,无法获取到令牌的请求可以丢弃,或者重试。下面我们来看一下的令牌桶示意图:
- 时间窗口
时间窗口又分为固定窗口
和滑动窗口
。
- 固定时间窗口:
原理:固定时间内统计流量总量,超过阀值则限制流量。
缺陷:无法限制短时间之内的集中流量。
- 滑动窗口原理:
原理:统计的总时间固定,但时间段是滑动的。
缺陷:无法控制流量让它们更加平滑
降级
网站处于流量高峰期,服务器压力剧增,根据当前业务情况及流量,对一些服务和页面进行有策略的降级(停止服务,所有的调用直接返回降级数据)。以此缓解服务器资源的压力,保证核心业务的正常运行,保持了客户和大部分客户得到正确的响应。降级数据可以简单理解为快速返回了一个 false,前端页面告诉用户“服务器当前正忙,请稍后再试。”
- 熔断和降级的相同点?
- 熔断和限流都是为了保证集群大部分服务的可用性和可靠性,防止核心服务崩溃。
- 给终端用户的感受就是某个功能不可用。
- 熔断和降级的不同点?
- 熔断是被调用方出现了故障,主动触发的操作。
- 降级是基于全局考虑,停止某些正常服务,释放资源。
故障转移
故障转移分为两种:完全对等节点的故障转移
和不对等节点的故障转移
。
- 对等节点的系统中,所有节点都承担读写流量,并且节点不保存状态,每个节点就是另外一个的镜像。如果某个节点宕机了,按照负载均衡的权重配置访问其他节点就可以了。
- 不对等的系统中,有一个主节点,多个备用节点,可以是热备(备用节点也在提供在线服务),也可以是冷备(只是备份作用)。如果主节点宕机了,可以被系统检测到,立即进行主备切换,而如何检测主节点宕机,就需要用到分布式 Leader 选举的算法,常见的就有 Paxos 和 Raft 算法
超时控制
超时控制就是模块与模块之间的调用需要限制请求的时间,如果请求超时的设置得较长,比如 30s,那么当遇到大量请求超时的时候,由于请求线程都阻塞在慢请求上,导致很多请求都没来得及处理,如果持续时间足够长,就会产生级联反应,形成雪崩。
还是以我们最熟悉的下单场景为例:用户下单了一个商品,客户端调用订单服务来生成预付款订单,订单服务调用商品服务查看下单的哪款商品,商品服务调用库存服务判断这款商品是否有库存,如有库存,则可以生成预付款订单。
- 第一次滚雪球:库存服务不可用(如响应超时等),库存服务收到的很多请求都未处理完,库存服务将无法处理更多请求。
- 第二次滚雪球:因商品服务的请求都在等库存服务返回结果,导致商品服务调用库存服务的很多请求未处理完,商品服务将无法处理其他请求,导致商品服务不可用
- 第三次滚雪球:因商品服务不可用,订单服务调用商品服务的的其他请求无法处理,导致订单服务不可用。
- 第四次滚雪球:因订单服务不可用,客户端将不能下单,更多客户将重试下单,将导致更多下单请求不可用。
所以设置合理的超时时间非常重要。具体设置的地方:模块与模块之间、请求数据库、缓存处理、调用第三方服务。
资源隔离
每个服务看作一个独立运行的系统,即使某一个系统有问题,也不会影响其他服务。常规的方案是使用两款组件:Sentinel
和 Hystrix
。
自动恢复和容灾
借助SRE运维平台实现集群的自动恢复和容灾。
故障演练
Java体系中故障故障演练平台在国内最有名也是最常用的就是ChaosBlade,我们可以借助ChaosBlade进行故障演练,模拟可能在生产环境遇到的问题,方便我们提前预知问题。
可视化监控平台
每家公司的监控平台都不一样,但是确实必不可少的,没有可视化的监控平台我们就像瞎子一样,出了问题只能靠猜。
报警
报警也是必不可少的,不然我们怎么在第一时间止损呢。
异地多活
异地多活是具有一定规模的互联网公司基本上都会做的事情,异地多活的意义在于某个服务挂了,其他服务随时切换到其他地域的机房中,从而保证服务的高可用。但是因为要做异地多活,所以服务是多套的,那么就要考虑数据库是不是需要共用数据库
。
- 共用数据库
- 不共用数据库
不论使用哪种方式,都涉及到跨机房数据传输延迟的问题(以下数字仅供参考)
- 同地多机房专线,延迟 1ms~3 ms。
- 异地多机房专线,延迟 50 ms 左右。
- 跨国多机房,延迟 200 ms 左右。
同城双活
高性能的同城双活,核心思想就是避免跨机房调用。
- 保证同机房服务调用:不同的 PRC(远程调用) 服务,向注册中心注册不同的服务组,而 RPC 服务只订阅同机房的 RPC 服务组,RPC 调用只存在于本机房。
- 保证同机房缓存调用:查询缓存发生在本机房,如果没有,则从数据库加载。缓存也是采用主备的方式,数据更新采用多机房更新的方式。
- 保证同机房数据库查询:和缓存一样,读取本机房的数据库,同样采用主备方式。
异地多活
同城双活无法做到城市级别
的容灾,所以需要考虑异地多活。
比如成都的服务器宕机了,还有北京的服务器可以顶上来。但两地距离不要太近,因为发生自然灾害时有可能会被另外一地波及到。和同城双活的核心思想一样,避免跨机房调用。但是因为异地方案中的调用延迟远大于同机房的方案,所以数据同步是一个非常值得探讨的点。提供两种方案:
- 基于存储系统的主从复制:MySQL 和 Redis 天生就具备,但是数据量很大的情况下,性能是较差的。
- 异步双写的方式:基于消息队列,将数据操作作为一个消息放到消息队列,另外的机房消费这条消息,操作存储组件。
两地三中心
这个概念也被业界提到过很多次。
两地:本地和异地。
三中心:本地数据中心、同城数据中心、异地数据中心。
这两个概念也就是我上面说的同城双活和异地多活的方式,只是针对的是数据中心。原理如下图所示:
B站崩了、Facebook崩了,我们到底该怎么保证高可用相关推荐
- B 站崩了,总结下「高可用」和「异地多活」
你好,我是悟空. 一.背景 不用想象一种异常场景了,这就真实发生了:B 站晚上 11 点突然挂了,网站主页直接报 404. 手机 APP 端数据加载不出来. 23:30 分,B 站做了降级页面,将 4 ...
- 稳定性和高可用如何保障?一手测评华为云网站高可用解决方案
一.前言 在如今科技高速发展的时代,几乎每个企业都依赖互联网,离不开互联网.很多企业的业务也都依托于互联网,比如我们熟知的电商.股市,直播.甚至是用于乘坐地铁.公交买票过闸的APP.如今可以说是一个互 ...
- 【j360-boot】Spring-boot系列三(崩溃模式,不是你崩就是电脑崩)
2019独角兽企业重金招聘Python工程师标准>>> j360-boot spring-boot入门工程之j360-boot:(欢迎star.fork) https://githu ...
- 月均活跃用户达1.3亿,B站高可用架构实践
流量洪峰下要做好高服务质量的架构是一件具备挑战的事情,本文详细阐述了从 Google SRE 的系统方法论以及实际业务的应对过程中出发,一些体系化的可用性设计.对我们了解系统的全貌.上下游的联防有更进 ...
- Bilibili高可用架构【B 站在云+社区沙龙分享干货】
来源:kunzhao.org/docs/cloud-plus-bbs/bilibili-high-availability/ [导读]本文整理了 B 站在云+社区沙龙分享的高可用架构,一起来学习小破站 ...
- 一页技术:B站高可用架构实战总结
最近,在云+社区听到了B站技术总监毛剑关于B站高可用的实践的分享,内容丰富,干货满满,本人对该分享的内容进行了总结,形成了思维导图的形式,便于以后快速回顾. 参考文献: Google - Site R ...
- B站崩了上热搜,说好的高可用呢?
来源:zhihu 编辑:Emil.小匀 一夜之间,年轻人最喜欢的弹幕视频网站突然崩溃了半小时,随后A站.豆瓣也如出一辙.有网友称「着火」所至,但上海消防队随后出来辟谣.那么,究竟是怎么回事? 崩了! ...
- 昨晚B站、A站、豆瓣都崩了,作为程序员,你不会真以为是肖战搞的鬼吧?
现在是凌晨2点多,学东西学到了这个点,本来我是准备刷刷朋友圈就睡了的,但打开了朋友圈之后我发现了惊奇的一幕:B站.A站和豆瓣崩溃了. 我瞬间就清醒了,这种"百年难得一见"的怪事居然 ...
- 2021.07.13【B站】是这样崩的
至暗时刻 2021年7月13日22:52,SRE收到大量服务和域名的接入层不可用报警,客服侧开始收到大量用户反馈B站无法使用,同时内部同学也反馈B站无法打开,甚至APP首页也无法打开.基于报警内容,S ...
- B站、豆瓣都崩了,还有啥技术能靠得住?
未来的软件,从诞生起,就是生在云上,长在云上的.这个说法绝对不是没有根据的,看看现在的互联网大厂在做的事情,你就知道了: 阿里宣布成立云原生技术委员会,并投入数十亿大力推动阿里经济体全面云原生化,对外 ...
最新文章
- Map接口及其常用方法
- 读“Agile Method – by Martin Fowler”总结和感想
- 【Linux部署】elasticsearch can not run elasticsearch as root+vm.max_map_count [65530] is too low 问题解决
- 阿里云ECS——[您的云服务器(xxx.xxx.xxx.xxx)由于被检测到对外攻击,已阻断该服务器对其它服务器端口(TCP:6379)的访问]解决方案
- VTK:Kochanek样条用法实战
- fusionsphere的核心组件_FusionSphere架构详解
- gitlab 使用现有 nginx 服务器
- jni4net调用net库
- 一文教你安全的关闭线程池
- [转]printf 函数实现的深入剖析
- SpringSecurity实战(一)-认证鉴权流程
- Google 人机验证(reCaptcha)无法显示解决方案
- css实现跳动的心形图案
- 模板字符串`${}` 各种函数中的this指向?
- 荐:Java常见设计模式
- ORA-01858 :在要求输入数字处找到非数字字符
- Unity数据持久化——Json
- 生成全局唯一ID的3个思路
- 趣图:谁说理工男都穿格子衫?
- 使用Bmob遇到的坑与解决办法
热门文章
- 互联网日报 | 1月27日 星期三 | 支付宝集五福活动2月1日开启;华为否认“出售手机业务”传闻;中国联通自有手机品牌发布...
- protoc导出时遇到protoc-gen-go unable to determine Go import path解决方法
- 压缩解压缩文件zlib
- SEO应届生,如何快速的了解SEO?
- 奥斯汀页眉怎么设置_word页眉怎么插入及删除
- CMD如何直接运行文件
- Bar Chart Race」动态可视化
- 水星怎么设置网速最快_水星路由器怎么设置网速 - 卡饭网
- 显微镜下的大明内容_《显微镜下的大明》读后感1000字
- 【Python数据分析】二手车价格预测