做一个不崩溃的icode9核酸系统有多难?
作者:互联网
热度已经过了,但还是觉得有必要从架构设计的角度来讨论一下此事。并用以往我的经验来设计一套负载能力更好一些的系统。
先说一下基本的架构思路:
- 最大限度的避免计算,静态化
- 不用数据库,更新类操作使用APPEND模式的文本文件
- 流程最短,最好是客户端访问的第一台服务器就能完成全部工作
- 善用CDN
- 客户端负载均衡
需求分析
- 扫码:通过调用URL将人访问过该地址的信息记录,以便有出现阳性时追访
- 获取当前人的健康码状态,显示到页面
页面中显示的字段信息包括:
- 健康码状态:绿码/黄码/红码等
- 最近一次核酸至今的时间:1天
- 疫苗接种情况
- 基本身份信息:姓名、身份证号
- 时间:查询时间,失效时间
常规设计思路与失效
一个只设计过常规MIS系统的工程师,满足如上需求的常规做法如下:
- 建立数据库,分别用几个表格来记录用户信息、核酸记录、疫苗记录、到访记录
- 用户扫码提交到访信息,就在到访记录表中INSERT一条新的记录
- 健康码页面的显示,依次去查询如上四个表来获取结果,其中后三个表需要排序后显示创建日期最新的记录
- 祭天,上线
然后遇到流量冲击,系统崩溃。崩溃的原因分为几个:
- 提交到访信息时,数据库只能承受几十到几千QPS的INSERT请求,对其他扫码请求无法处理,导致用户提交的请求失败
- 四个表的查询,对数据库造成了巨大的查询压力,数据库服务器LOAD爆了
资深架构师的改造思路
5-10年经验的工程师/架构师的典型改造思路:
- 数据库横向拆表到多个数据库服务器,每个数据库按照一定的负载均衡逻辑,只保留一部分数据,比如用户ID整除10后的余数,分布到10台数据库。于是工程师熬夜加班,确保查询时会根据负载均衡逻辑去正确的服务器查询,提交到访记录时也会INSERT到正确的服务器
- 入口加负载均衡,DNS解析到多个机房的入口Load Balance,然后Load Balance再随机分派给多台后端服务器,多堆服务器提高处理能力
- 数据冗余降压力:把最新一条的核酸记录、疫苗记录,作为冗余字段写入到用户表里,这样显示健康宝页面时就少查询了两个表
- 查询时间、失效时间,两个字段在客户端生成,不问数据库要
- 搞个消息队列,先返回给用户查询中,等个未知的时间都算完了再返回
通过这样一套操作下来,整个系统的负载能力能获得几十倍到几百倍的提高。
但很不幸,有些时候就是会有数千倍甚至数万倍的流量涌过来。
首问负责制
想要更强的负载能力,就需要若干改造思路。
所谓首问负责制,是让用户的请求尽量在第一个服务器就得到全部的满足。如果不行,也要尽最大能力降低完成一个请求经历的服务器数量。网络通常是整个系统里最慢的部分,服务器之间的互相调用也会严重的影响系统负载能力。
所以目标就是,让用户访问的第一台服务器就完成提交到访记录、获取用户健康宝全部信息。