共计 2741 个字符,预计需要花费 7 分钟才能阅读完成。
1. 解体的一天
12 月 20 号,算得上西安解体的一天。
12 月 19 号新增病例 21 个,20 号新增病例 42 个,并且有局部病例曾经在社区内流传 …
西安防疫压力微小,各单位公司要求,需 48 小时核酸检测报告下班。
在这样严厉的状况下,作为防控最外围的零碎:西安一码通居然解体了,并且解体得是那么的彻底。
足足瘫痪超过 15+ 个小时!
整整一天的工夫呀,多少上班族被堵在地铁口,多少旅客被冻在半路上,进退不能 …
到了下午,新闻甚至提醒:
为了加重零碎压力,倡议宽广市民非必要不展码、亮码,在呈现零碎卡登时,请急躁期待,尽量避免重复刷新,也感激宽广市民敌人们的了解配合。
这是解决问题的办法吗?
如果真的须要限流来避免零碎解体,用技术手段来限流是不是会更简略一些,甚至后面加一个 nginx 就能解决的问题。
明天,咱们就试着剖析一下这个业务、以及对应的技术问题。
2. 产品剖析
西安一码通其它业务咱们暂且不剖析,那并不是重点,并且当天也没有齐全解体,解体的仅有扫码性能。
其实这是一个十分典型的大量查问、多数更新的业务,闭着眼睛剖析一下,能够说,90% 以上的流量都是查问。
咱们先来看看第一版的产品状态,扫码之后展现集体局部姓名和身份证信息,同时上面展现绿、黄、红码。
这是西安一码通最开始的样子,业务流程仅仅只须要一个申请,甚至一个查问的 SQL 就能够搞定。
到了起初,这个界面做了 2 次比拟大的改版。
第一次改版新增了疫苗接种信息,加了一个边框;第二次改版新增了核酸检测信息,在最下方展现核酸检测时间、后果。
整个页面减少了 2 个查问业务,如果零碎背地应用的是关系数据库,可能会多减少至多 2 个查问 SQL。
基本上就是这样的一个需要,据统计西安有 1300 万人口,依照最大 10% 的市民同时扫码(我狐疑不会有这么多),也就是百万的并发量。
这样一个并发量的业务,在互联网公司很常见,甚至比这个简单的场景也多了去了。
那怎么就崩了呢?
3. 技术剖析
在当天早晨的官网回复中,咱们看到有这样一句话:
12 月 20 日早 7:40 分左右,西安“一码通”用户访问量激增,每秒访问量达到以往峰值的 10 倍以上,造成网络拥塞,以致包含“一码通”在内的局部利用零碎无奈失常应用。“
一码通”后盾监控第一工夫报警,各 24 小时驻场通信、网络、政务云、平安和运维团队立刻发展排查,平台利用零碎和数据库运行失常,判断问题呈现在网络接口侧。
依据下面的信息,数据库和平台零碎都失常,是网络呈现了问题。
我之前在文章《一次 dns 缓存引发的惨案》画过一张拜访示意图,用这个图来和大家剖析一下,网络呈现问题的状况。
个别用户的申请,会先从域名开始,通过 DNS 服务器解析后拿到外网 IP 地址,通过外网 IP 拜访防火墙和负载之后打到服务器,最初服务器响应后将后果返回到浏览器。
如果真的是网络呈现问题,个别最常见的问题就是 DNS 解析谬误,或者外网的宽带被打满了。
DNS 解析谬误肯定不是本次的问题,不然可能不只是这一个性能出错了;外网的宽带被打满,间接减少带宽就行,不至于一天都没搞定。
如果真的是网络侧呈现问题,个别也不须要改变业务,但实际上零碎复原的时候,大家都发现界面回到文章结尾提到了第一个版本了。
也就是说零碎“回滚”了。
界面少了接种信息和核酸检测信息的内容,并且在一码通的首页地位,新减少了一个核酸查问的页面。
所以,仅仅是网络接口侧呈现问题吗?我这里有一点点的疑难。
4. 集体剖析
依据我以往的教训,这是一个很典型的零碎过载景象,也就是说短期内申请量超过服务器响应。
说人话就是,内部申请量超过了零碎的最大解决能力。
当然了,零碎最大解决能力和零碎架构非亲非故,同样的服务器不同的架构,零碎负载量差别极大。
应答这样的问题,解决起来无非有两个计划,一个是 限流 ,另外一个就是 扩容 了。
限流就是把用户挡在里面,先解决能解决的申请;扩容就是加服务器、减少数据库承载能力。
下面提到官网让大家没事别刷一码通,也算是人工限流的一种形式;不过在技术体系上基本上不会这样做。
技术上的限流计划有很多,但最简略的就是后面挂一个 Nginx 配置一下就能用;简单一点就是接入层本人写算法。
当然了限流不能真正的解决问题,只是负责把一部分申请挡在里面;真正解决问题还是须要扩容,满足所有用户。
但实际上,依据解决问题的解决和产品回滚的状况来看,一码通并没有第一工夫做扩容,而是抉择了回滚。
这阐明,在零碎架构设计上,没有充分考虑扩容的状况,所以并不能反对第一工夫抉择这个计划。
5. 现实的计划?
下面说那么多也仅仅是集体揣测,实际上可能他们会面临更多事实问题,比方工期缓和、老板管制估算等等 …
话说回来,如果你是负责一码通公司的架构师,你会怎么设计整个技术计划呢?欢送大家留言,这里说说我的想法。
第一步,读写拆散、缓存。
至多把零碎分为 2 大块,满足日常应用的读业务独自抽取进去,用于承接内部的最大流量。
独自抽出一个子系统负责业务的更新,比方接种信息的更新、核酸信息的变动、或者依据业务定时变更码的色彩。
同时针对用户大量的单查问,上缓存零碎,优先读取缓存零碎的信息,避免压垮前面的数据库。
第二步,分库分表、服务拆分。
其实用户和用户之间的单个查问是没有关系的,齐全能够依据用户的属性做分库分表。
比方就用用户 ID 取模分 64 个表,甚至能够分成 64 个子系统来查问,在接口最前端将流量散发掉,加重单个表或者服务压力。
下面剖析没有及时扩容,可能就是没有做服务拆分,如果都是单个的业务子服务的话,遇到过载的问题很容易做扩容。
当然,如果条件适合的话,上微服务架构就更好了,有一套解决方案来解决相似的问题。
第三步,大数据系统、容灾。
如果在一个页面中展现很多信息,还有一个技术计划,就是通过异步的数据荡涤,整合到 nosql 的一张大表中。
用户扫描查问等相干业务,间接走 nosql 数据库即可。
这样解决的益处是,哪怕更新业务齐全挂了,也不会影响用户扫码查问,因为两套零碎、数据库都是齐全离开的。
应用异地双机房等模式部署服务,同时做好整体的容灾、备灾计划,避免出现极其状况,比方机房光缆挖断等。
还有很多细节上的优化,这里就不一一阐明了,这里也只是我的一些想法,欢送大家留言补充。
6. 最初
不管怎么剖析,这必定是人祸而不是人祸。
零碎在没有通过严格测试之下,就间接投入到生产,在强度略微大一点的环境中就解体了。
比西安大的城市很多,比西安当初疫情还要重大的状况,其它城市也遇到过,怎么没有呈现相似的问题?
西安做为一个科技大省,呈现这样的问题真的不应该,特地是我看了这个小程序背地应用的域名地址之后。
有一种有力吐槽的感觉,尽管说这和程序应用没有关系,然而从细节真的能够看出一个技术团队的实力。
心愿这次可能吸取教训,防止再次出现相似的问题!
举荐浏览:《西安衰弱一码通崩了!程序员抢修居然被……》