有图有真相,我们先上图。
在上述图中,我们明显可以看到,全链路压测有几个关键部分:
数据工厂,负责造请求数据。
大流量下发器,产生很大的压力去压系统。
线上服务集群同时处理压测请求 + 正常请求。
压测流量落影子存储,正常流量落正常存储。
压测流量对于外部的依赖走 mock 服务器,正常流量走正常外部集群。
水位检测,需要检测存储 + 线上应用服务器的健康度,并且能够干预流量下发。
数据工厂是压测的一个核心部件,主要由 Hive 表的集合 + 各种导入、导出脚本组成。
数据工厂的目的是保存压测需要准备的所有数据,数据需要做清洗,比如:
商品未下架
商品的库存无限
营销活动的信息有效,未过期
店铺未关闭等等
场景的定义:场景的定义关系到数据的准备,正常来说,压测只会压随着买家人数暴增、系统的压力立即增加的场景,我们把这个场景涉及到的系统叫做“核心链路”。
DB、路由方式由 RDS 提供,存储可以有两种方式:
影子表与正常表存在同样的 instance、不同的 schema 中。这个方案不需要增加额外的存储开销,相对更便宜,但是风险较高(把库压死了会影响线上业务)。
影子表与正常表存在不同的 instance、相同的 schema 中。这个方案相对较贵,需要额外搭建 DB 集群,但是安全性较高。
我们选择的是第一个方案。
Redis:通过 key 值来区分。压测流量的 key 值加统一前缀,通过 Redis-Client 做路由。
HBase:通过命名空间做隔离。影子空间加前缀,提供统一的 HBase Client 做数据访问,由该 Client 做路由。
ES:通过 index 名字来区分。影子的索引统一加前缀,提供统一的 ES Client 做数据访问,由该 Client 做路由。
统一线上应用对于数据的访问(DB+ES+HBase+Redis),提供统一的 Client。
由于线上的应用都是服务化工程,远程调用时,必须具备压测流量的标记透传能力。
线上的少部分应用,需要访问第三方服务,比如:物流、支付。这些应用需要改造为压测的流量直接访问 mock 服务器。
我们选用 gatling 作为我们的流量下发器实现。
数据文件的内容
每一种场景都有不同的数据文件,数据文件由场景相对应的多种 url 组合而成。比如:我们本次压测会压“无优惠的场景、秒杀场景、满减场景、拼团场景” 等等。无优惠的场景分为“店铺首页、商品详情页、加购物车页、下单页、支付页、支付成功页”等等。这个文件不涉及漏斗转化率。一般来说,一个数据文件很大(至少是 G 级别的)。所以我们的数据文件内容格式为:
所有的数据⽂文件
场景集合 1
场景集合 2
店铺首页 URL
商品详情页 URL
加购物车页 URL
下单页 URL
支付页 URL
支付成功页 URL
店铺首页 URL
商品详情页 URL
加购物车页 URL
下单页 URL
支付页 URL
支付成功页 URL
无优惠的场景数据文件
秒杀场景数据文件
满减场景数据文件
拼团场景
流量下发脚本的内容
流量下发脚本的核心是控制漏斗转化率:
不同场景的流量配比。
每个场景下面,url 从上往下的漏斗转化率。
gatling 提供天然的转化率配置脚本,用起来非常方便。有兴趣的同学可以自行 Google。