3.2 压测隔离压测隔离中需要解决的压测流量隔离,以及压测数据的隔离 。
压测流量隔离,主要是通过构建压测环境来解决,如线下压测环境,或泳道化/Set 化建设,将压测流量与线上流程完全隔离 。优点是压测流量与线上流量完全隔离,不会影响到线上用户 。缺点:机器资源及维护成本高,且压测结果需要经过一定的换算,才能得线上容量,结果准确性存在一定的问题 。目前公司内压测都是在线上集群上完成的,线上泳道化正在建设中 。
压测数据隔离,主要是通过对压测流量进行染色,让线上服务能识别哪些是压测流量,哪些是正常流量,然后对压测流量进行特殊处理,以达到数据隔离的目的 。目前 Rhino 平台整体压测隔离框架如图 。

文章插图
压测标记压测标记就是最常见的压测流量染色的方式 。
- 对于 RPC 协议,会在请求的头部中增加一个 Key:Value 的字段作为压测标记 。
- 对于 HTTP 和其他协议,会在请求头,自动注入一个 Stress 标记(Key-Value)。
- 压测标记 Key:Value,其中 key 是固定的 Stress_Tag 值,但是每个压测任务都有唯一的 Stress_Value 值,主要用于解决压测数据冲突,以及性能问题定位 。
Golang 服务: 将压测标记写入 Context 中 。
Python 服务:利用 threading.local()存储线程 Context 。
JAVA 服务:利用 ThreadLocal 存储线程 Context 。
压测开关为了解决线上压测安全问题,我们还引入了压测开关组件 。
- 每个服务每个集群,都有一个压测开关 。只有打开压测开关时,压测流量才能流入到服务内,否则就会被底层微服务框架直接拒绝,业务层无感知 。
- 在每个 IDC 区域,都会有一个全局的压测总开关 。只有打开了这个全局压测开关,压测流量才被允许在这个 IDC 内流转 。
- 当线上出现压测问题,除了从源头关闭压测流量以外,关闭目标服务的压测开关,也能立即阻断压测流量 。
Rhino 平台针对不同存储,有不同的解决方案:
- MySQL、MongoDB:影子表 。SDK 判断是否是压测流量,若是则根据配置映射至新表名 。配置策略有两种,一是读写影子表,二是读线上表、写影子表 。
- redis:Redis Key 加上 Stress 前缀 。如 Stress_Tag=Valuex,那么读写 Redis 的 Key=Valuex_Key 。这样可以解决多个压测任务数据冲突的问题 。压测结束后,只需要对 Prefix=Valuex 做清除或过期操作即可 。
- MQ:对于消息队列,Rhino 平台有两种策略 。一是直接丢弃,然后针对消息队列的性能,单独进行压测;二是在 Header 中透传压测标记,Consumer 根据压测标记和业务需求,再做特殊处理 。默认走丢弃策略,业务方可根据需求进行配置 。
- 其他存储,如 ES,ClickHouse 等,都有压测集群 。压测时,会将压测请求打到指定的压测集群中 。

文章插图
服务压测改造在压测之前,需要对服务进行压测验证 。对于不满足压测要求(即压测数据隔离)的服务,需要进行压测改造 。
- 压测验证:对于存储服务,在不打开压测开关的前提下,通过压测请求,发送读写操作都是会被拒绝 。如果没有拒绝,说明在操作存储服务时,没有带上压测 Context,需要进行改造 。
- 压测改造:压测改造是线上全链路压测推进中非常关键,而又非常困难的一个环节 。对于已经上线的服务,压测改造还极有可能会引入新的 BUG,所以经常推动起来比较困难 。因此为了解决这些问题,Rhino 平台有以下几个解决方案:
b. 提供简单便捷的线上线下 HTTP&RPC 的压测请求 Debug 工具,方便代码改动的验证
推荐阅读
- YARN 在字节跳动的优化与实践
- 胎心115
- 字节跳动自研线上引流回放系统的架构演进
- 算法血拼:Google+百度+Alibaba+字节+Tencent+网易+360+拼夕夕
- kb是什么意思啊?
- 字节跳动面试必会:快速选择算法,TopK问题最优解
- 肚子在跳动是什么呢
- 刷透近200道数据结构与算法,成功加冕“题王”,挤进梦中的字节
- 黑客教程——Padding Oracle Attack&CBC字节翻转攻击详解
- JAVA字节流、字符流、缓冲流、转换流、内存流、字符编码
