提高一个系统的可用性的最有效方式就是通过测试进行验证。软件系统测试的方案有很多种,功能测试还是非功能测试,在什么环境测试,在软件生命周期的什么阶段测试,这些都会决定我们采用不同的测试方案。
最佳的验证方法就是让事件提前发生,即让真实的流量来访问生产环境,实现全方位的真实业务场景模拟,确保各个环节的性能、容量和稳定性均做到万无一失。这是全链路压测产生的背景。
全链路压测是指全业务覆盖、全链路覆盖的系统压测方式,要真正做到全业务全链路,就必须在线上生产环境实施压测,必须用线上的真实数据、线上的真实流量请求、同等的用户规模、同等的业务场景,来对完整的应用系统实施从网络、应用、中间件、数据、服务器、外部依赖等进行全覆盖的压测,并持续调优的过程,以找到系统的瓶颈点,对系统容量进行真实客观的预估。
全链路压测是应对当前复杂分布式环境下,系统面临的诸多不确定性可能导致系统可用性问题的一套解决方案。由于真实世界很难被100%模拟,常规的功能测试、非功能测试无法确保线上系统的稳定可靠,分布式环境下单个系统ready不代表全局ready。系统不可用的原因可能是分布式环境全链路中任意一个环节出了问题,全链路压测解决方案通过技术手段模拟海量用户的真实业务场景,让所有性能问题无所遁形,解决客户线上系统面临的以下痛点:
- 线上关键业务系统的稳定可靠,关乎企业的生死存亡。
- 测试一切安好,生产却莫名出各种问题。
- 分布式系统拆分后,在测试环境运行得很好,每个子系统似乎都没问题,但全局整体系统会出问题。
- 资源不合理分配,有的忙,有的闲,存在浪费。
- 想做业务创新,但不知道该投入多少资源预算。
网站和App类的用户都有全链路压测的需求,用来检测在各类场景下产品的性能,以便在上线前(或者大促活动前)提前发现性能问题。在大型复杂分布式应用系统中,全链路压测解决方案对提高最终交付系统的可靠性起到保障作用,具体的应用场景如下:
- 新系统上线:通过全链路压测准确探知站点能力,防止系统一上线就被用户高并发流量打垮。
- 技术升级验证:大的技术架构升级后进行性能评估,以验证新技术场景的站点性能状态,防止技术升级影响业务的正常运行。
- 业务峰值稳定性:大促活动等峰值业务稳定性考验,保障峰值业务不受损。
- 站点容量规划:对站点进行精细化的容量规划,分布式系统机器资源分配,提高资源的整体利用率。
- 性能瓶颈探测:探测系统中的性能瓶颈点,进行有针对性的优化,以最小的投入带来性能的最大提升。
全链路压测方案实施过程包括压测场景梳理(性能目标、时序图、状态图、系统架构、数据架构、技术架构)、全链路压测执行步骤、技术要点、环境改造(影子表、序列隔离、挡板拦截、mock、日志过滤、压测标识传递)、打底数据导入、压测数据(参数化)准备、工具支持等。
在一个应用系统准备实施全链路压测之前,首先需要确定具体的压测模式和场景,对于生产环境压测和测试环境压测,所要做的前期准备工作是完全不一样的;而仅压测只读流量,还是读写流量同时压测,二者对系统的影响也是不一样的。
全链路压测的所有数据都在生产环境做了数据隔离,包含存储、缓存、消息、日志等一系列的状态数据。在压测请求上会打上特殊的标记(压测标识),这个标记会随着请求的依赖调用一直传递下去。任何需要对外写数据的地方都会根据这个标记的判断写到隔离的区域,我们把这个区域叫作影子区域。
对数据库而言,一般通过在业务数据库中创建影子表来建立影子区域。影子表是指表结构跟正常业务表完全一样的测试表(一般通过表特殊命名加以区分,如影子表为正常业务表加固定前缀),数据库持久层代理需要识别压测流量,并把压测流量的数据读写全部路由到影子表中,通过这样的方式实现压测数据的隔离。采用影子表的方案主要是为了方便压测数据的路由,以及压测结束后的数据清理还原。
在压测过程中,对于所有调用的外部第三方服务,一般无法要求进行压测改造,我们通过挡板mock的方式进行拦截仿真,以防止压测对外部系统产生流量负担及数据污染。