在每年的京东”618″及淘宝的”双11″活动中,平台商家会有很多促销商品,而且商品价格对于用户来说吸引力巨大。
面对这么巨大的流量,技术上如何保证这些商品不被”超卖”,同时还能给用户一个良好的购物体验?
12306网站在刚开始对外在线售票时,经常出现系统瘫痪的现象,后来经过系统优化,现在已经可用支持上千万人同时抢票且不损害系统本身。
这些技术的背后都离不开高并发技术,需要利用高并发技术的方法论及设计原则,再结合业务本身进行架构设计,以应对系统面临的流量冲击
1. 什么是高并发
高并发(High Concurrency),通常是指通过设计保证系统能够同时处理很多请求。
即在同一个时间点,有很多的请求同时访问同一个接口。
高并发意味着大流量,需要运用技术手段去抵抗这种大流量的冲击,以达到系统能平稳处理流量且系统自身依然运行良好的目的。
现如今,高并发场景无处不在,例如京东的”618″、淘宝的”双11″、热门车次车票的开售,以及各种电商秒杀抢购活动等。
高并发是一种系统在运行过程中,”短时间内遭遇大流量冲击”的情况。
如果没有处理好,则很有可能造成系统吞吐量下降,响应变慢,从而影响用户体验,甚至可能造成系统彻底不可对外服务的情况发生。
所以,需要优化系统(包括硬件、网络、应用、数据库等)来达到高并发的要求。
2. 高并发系统有哪些关键指标
在设计一个系统或对已有系统进行性能评估时,需要具备相应的参考指标,然后基于这些参考指标对系统进行针对性的优化,使得系统更健壮,以及具备更高的性能。
接下来看看高并发系统都需要关注哪些关键指标。
响应时间(Response Time)
响应时间,是指从第一次发出请求到收到系统完整响应数据所需的时间。
响应时间是反映系统性能的重要指标,直接反映了系统响应的快慢。
- 从用户角度出发,响应时间决定着用户的体验感:响应时间越长,用户体验感越差,就会造成用户的流失;响应时间越短,用户体验感越好,有助于提高用户留存率。
- 从系统本身的角度出发,响应时间决定着系统的性能问题:响应时间越短,系统性能越高,即能更好地处理业务;响应时间越长,系统性能越差,甚至可能会丢失相关请求或者出现系统不可用,从而影响公司业务。
吞吐量(Throughput)
吞吐量指单位时间内系统所处理的用户请求数。
- 从业务角度看,吞吐量可以用”请求数/秒””人数/天”或”处理业务数/小时”等单位来衡量
- 从网络角度看,吞吐量可以用”字节数/秒”来衡量。
对于互联网应用来说,吞吐量能够直接反映系统的负载能力。
采用不同方式表达的吞吐量,可以说明不同层次的问题,如:采用”请求数/秒”方式的吞吐量,则说明瓶颈主要来源于应用服务器和应用本身;
采用”字节数/秒”方式的吞吐量,则说明瓶颈主要来源于网络基础设施、服务器架构和应用服务器约束等。
在没有遇到性能瓶颈时,吞吐量与虚拟用户数之间存在一定的联系,可以采用以下公式计算吞吐量:
F = VU x R/T
其中,F表示吞吐量,VU表示虚拟用户个数,R表示每个虚拟用户发出的请求数,T表示性能测试所用的时间。
每秒请求数(QPS)
QPS指服务器在一秒内共处理了多少个请求,主要用来表示”读”请求。
在系统上线前,一般怎么预估系统QPS呢?
绝大部分系统在白天的请求量都比较大,所以,这里假设以白天来计算QPS。
依据二八原则,80%的流量是在20%的时间段内产生的。
例如,现在每天有5000000个请求,预估QPS=(5000000 * 0.8)/(12 * 60 * 60 * 0.2) = 462。
即当前系统每天平均QPS为462。
当然,为了保险起见,再预留个20%左右也是可以的。
一般还需要计算当天最高QPS,这样对系统的掌控力度更强。
系统最高QPS,可以通过系统平均QPS的倍数计算出来。
例如,分析业务得到最高QPS大概是平均QPS的2倍,则当前系统峰值QPS为924左右。
在预估出QPS后,用”峰值QPS/单台机器最高可承受的QPS”就能计算出需要部署多少台服务器。
即:机器数 = 峰值QPS/单台机器最高可承受的QPS
单台最高可承受的QPS可以通过压测来得出。
假设单台机器压测得出最高可承受的QPS为100,则所需要的机器数量为:924/100 ≈ 10台。
每秒事务数(TPS)
TPS即服务器每秒处理的事务数。
TPS包括以下三个过程:
- 客户端请求服务端。
- 在服务端内部进行业务逻辑处理。
- 服务端响应客户端。
一个事务包括”客户端向服务器端发送请求+服务器响应”的过程。
在客户端发送请求时开始计时,在客户端收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。
TPS与QPS区别是什么呢?
QPS类似于TPS,但也有不同之处。
例如:当用户访问一个完整页面时,请求+响应的整个过程就是一个TPS;
但是,这一次完整的页面请求可能产生多次对服务器的请求,这些请求应计入QPS。
假设访问一个页面时会请求服务器三次,这样的一次访问会产生一个TPS,三个QPS。
访问量(PV)
PV(Page View)指页面浏览量。
用户每对网站中的一个网页访问一次均被记录一次。
用户对同一个页面的多次访问被累计记录。
PV是评价网站流量最常见的指标之一。
独立访客(UV)
UV(Unique Visitor)指访问某个站点或点击某个链接的不同IP地址数。
在同一天内,UV只记录第一次进入网站的具有独立IP地址的访问者,在同一天内访问者再次访问该网站则不计数。
独立IP地址访问者相当于携带了”身份证”进入网站,它能反映在一定时间内有多少独立客户端进行了访问。
一个UV可以有很多个PV,一个PV也可以对应一个IP。
例如,对网站访问一次,则网站的UV就加1;
这一次访问了该网站的两个页面,则网站的PV加2;
对其中一个网页又刷新了一次,则PV再加1.
网络流量
因为受限于带宽,所以网络流量(也简称流量)是并发情况的一个重要指标,主要涉及以下两个方面:
- 流入流量:从外部访问服务器所消耗的流量。
- 流出流量:服务器对响应的流量。
3. 对比单体系统、分布式系统和微服务系统
3.1 单体系统之痛
单体系统并非一无是处。
在某些场景中,单体系统是最佳的选择,可以帮助企业业务快速发展。
在企业初创期,投入较少的研发资源构建出适应当前业务的单体应用,从而达到抢占市场和技术试错的目的。
- 什么是单体系统
单体系统即一个应用程序,所有的业务代码都在这一个应用程序中,所有的表也都在一个数据库中,所涉及的相关文件都同一个服务器上。
在企业初创期,为了快速进入市场,一般企业都采用单体系统。
淘宝等电商平台在初创期也都采用的是单体系统。
在企业初创期,用户量不多,业务场景也不复杂,这正是验证技术和业务模式可行性之时,系统越简单越好,搭建过程越快越好。
于是,可以在同一台服务器上构建”1个应用程序+1个数据库+1个文件服务器”的单体系统,如下图所示。
![](https://ichiblog.cn/wp-content/uploads/2024/06/图片-58.png)
- 单体系统面临的问题
企业快速发展后,单体系统可能会面临以下问题:
- 需要频繁地合并1代码分支,影响项目的迭代进度。
- 多人协作耦合度高,测试效率低下。
- 开发节奏混乱,代码冲突频繁。
- 代码模块层次越来越复杂,业务边界变得不清晰。
- 项目越来越庞大,技术架构升级变得困难。
此时如果需要迭代系统版本或上新一个业务板块,则会涉及系统的多个业务。
例如,对于一个产品需求,可能会拉取多个分支(feature/A和feature/B)进行开发。
在开发feature/B过程中,由于业务需要修改了部分功能,这部分功能涉及feature/A的功能,然后进行测试,也通过测试了。
在之后开发feature/A过程中进行代码拉取及合并时,可能会出现各种代码冲突,这就需要花费大量的沟通成本去解决。
项目的参与人员越多,则代码冲突的概率就越大。
如果没有版本规划管理,那么这种低效的开发方式会严重阻塞产品版本迭代。
多人同时开发同一个项目,可能会出现随意修改彼此代码的风险,往往需要花费大量的沟通成本去解决问题。
而且这会增加测试的复杂度。
因为,每次版本迭代都需要对整个系统进行回归测试,之后才能将其上线。
而这是一个非常漫长的过程,会浪费测试人员很多的时间,并且,在测试通过的版本中也可能潜藏着一些测试人员没留意的问题。
单体系统一般采用三层架构,如图所示:
![](https://ichiblog.cn/wp-content/uploads/2024/06/图片-59.png)
- 用户展示层:负责用户端的展现和体验
- 业务层:负责业务的所有逻辑操作
- 数据访问层:负责操作数据库,如读写数据库等。
单体系统架构分层也有弊端:
- 从水平方向来看,的确降低了业务的深度复杂性。
- 从垂直方向来看,单体的业务边界不够清晰,因为在各层之间会进行网状的调用,比如,用户展现层的某个模块会调用业务层的多个模块(甚至所有的模块);业务层的模块同样会调用数据访问层的多个模块等。
通过上面的内容我们可以知道,单体项目当前的代码量已经非常庞大了,而且开发沟通成本也很大,业务模块的调用也异常复杂。
如果单体应用使用了很多的技术,且其中部分技术比较落后,则我们一般不愿意升级该单体应用,因为升级的成本很大:
要考虑整个系统的所有引用方是否有问题;
要验证当前架构的适应度;
即使强制升级了,还需要花费大量的时间进行全盘测试验证,灰度发布一段时间后才能正常使用。