链路压测需要注意些什么,踩过的坑

转自 https://blog.csdn.net/weixin_33810302/article/details/88609817

针对线上业务越来越大,越来越复杂、 知道业务系统的可用性、服务能力的瓶颈,满足业务技术需求, 让技术更好的服务业务。需要知道业务系统的容量和流量,做好容量规划,做好限流降级。全链路压测就是干这事。

点击查看隐藏内容🎁

链路压测主要流程是流量录制、回放、施压 。
链路压测需要关注的点是:梳理核心链路和边界、数据模型构建、流量平台搭建、流量复制

核心链路是一个业务的核心,这一块应该可以很快梳理清楚
难点在于梳理清楚链路的边界
千万不要污染正常数据:认真梳理数据处理的每一个环节,确保 mock 数据的处理结果不会写入到正常库里面。明确需要Mock的外部接口。
在核心链路的基础上,我们会有很多的分支业务,而这些分支业务有的可以参与压测,有的不能参与压测
比如给用户下放 push 消息
短信 / 支付 / 微信 Oauth 授权。
做好链路治理
(链路治理模块主要提供链路入口选取、链路标注、服务出口分析、出口Mock配置)

数据的真实性和可用性:可以从生产环境完全移植一份当量的数据包,作为压测的基础数据,然后基于基础数据,通过分析历史数据增长趋势,预估当前可能的数据量。获取原始真实的线上数据,场景回放流量。
数据脱敏:基于生产环境的全链路压测,必须考虑的一点是不能产生脏数据,以免对生产造成影响,影响用户体验等,因此在数据准备时需要进行数据脱敏
数据隔离:千万不要污染正常数据:认真梳理数据处理的每一个环节,,可以考虑通过压测数据隔离处理,落入影子库,mock对象等手段,来防止数据污染

jmeter、Ngrinder、locust,提供分布式压测的方式(饿了么的流量平台是基于 jmeter 改造的)、压测机中的机器数据能够实时的收集查看到、可以随时停止压测、一定时间内实时错误率达到阈值自动熔断。考虑到压测量较大的情况下回传测试结果会对 agent 本身造成一定资源占用,可以考虑异步上传,甚至事务补偿机制。

业务代码改造:压测请求上会打上特殊的标记,这个标记会随着请求的依赖调用一直传递下去。写请求写到影子区域(比如header头中做标记,存储、缓存、消息、日志等一系列的状态数据)、依赖的外部服务做 mock 处理(短信、邮件、push 等等)
真实流量蓄水池,分批释放
逐步压测

业务中需要区分流量(正常流量/压测流量)
压测时需要在 http header 里加入X-Shadow 的key ,值为 true 的代表压测,key 不存在或者 key 值不等于 true代表非压测流量
接收和发送 http / grpc 等请求时
在向下游服务发起请求时,如果是压测流量把 header 头中的标记字段往下透传,下游继续在业务中往下透传
接收到如果是压测流量,使用相应的压测数据
依赖的模块
MySQL 使用影子表,将压测流量对 MySQL 的读写打到影子表上。即正常的业务表名为A,则影子表名为A_shadow
所有涉及到的业务表都需要建一份影子表
便于事后数据的清理
MongoDB 使用影子 collection ,将压测流量对 MongoDB 的读写打到影子表上。即正常的业务表名为A,则影子表名为 A_shadow
同 MySQL
Redis 使用影子 key ,将压测流量对 redis 的读写打到影子 key 上。 如set key value 会变成 set key_shadow value
同 MySQL
kafka 使用影子 topic,key 后拼接 _shadow

  • 同 MySQL
    不需要参与压测的做 mock 处理
    给用户发push、短信、支付、微信Oauth授权

传统压测工具
ab、webbench、wrk、httpperf
简单、成本低
网络过于理想化、请求单一、同一客户端
基于web 服务器的请求复制
请求多样化、成本低
不具备通用性、丢失网络延迟、占用在线资源比较严重
mirror (基于应用层)
https://juejin.im/entry/5a4d9e10f265da43284144b0
https://github.com/session-replay-tools/mirror/blob/master/README.md
基于应用层的流量复制工具和基于网络栈的流量复制工具。前者实现简单,但会挤 占线上应用的资源(比如连接资源,内存资源等),还可能会因为耦合度高而影响正常业务。
而基于网络栈的流 量复制工具,直接从链路层抓取数据包,对应用影响较小,但是其实现也就相对复杂一些。
mirror是基于应用层的流量复制
tcpcopy (基于网络栈,tcp协议的流量复制)
https://blog.csdn.net/wangbin579
https://github.com/wangbin579/tcpcopy
http://tonylit.me/2016/10/19/tcpcopy/
解决传统压测、基于web服务器请求复制的问题
针对 TCP 的基于底层的在线请求复制工 具,可以用来帮助解决架构方面的大部分问题
在不影响在线使用的情况下,把线上的流量 复制并且引到测试环境中去,使其达到对 server 测试的目的
goReplay (http协议的流量复制)

为什么需要容量规划
容量规划的目的在于让每一个业务系统能够清晰地知道:什么时候该加机器、什么时候应该减机器?双11等大促场景需要准备多少机器,既能保障系统稳定性、又能节约成本
ps:什么时候增减机器、保障系统稳定性、节约成本

容量规划四步走
业务流量预估阶段:通过历史数据分析未来某一个时间点业务的访问量会有多大
系统容量评估阶段:初步计算每一个系统需要分配多少机器
容量的精调阶段:通过全链路压测来模拟大促时刻的用户行为,在验证站点能力的同时对整个站点的容量水位进行精细调整
流量控制阶段:对系统配置限流阈值等系统保护措施,防止实际的业务流量超过预估业务流量的情况下,系统无法提供正常服务
获取单台机器的服务能力
为了精准地获取到单台机器的服务能力,压力测试都是直接在生产环境进行,这有两个非常重要的原因:单机压测既需要保证环境的真实性,又要保证流量的真实性

单台机器压力测试的 4 个方法

通过对生产环境的一台机器发起模拟请求调用来达到压力测试的目的.
工具:apache ab、webbench、httpload、jmeter、loadrunner
适用场景:新系统上线或者访问量不大的系统采用这种方式来进行单机压测
缺点:模拟请求和真实业务请求之间存在的差异,会对压力测试的结果造成影响
另一个缺点在于写请求的处理比较麻烦,因为写请求可能会对业务数据造成污染,这个污染要么接受、要么需要做特殊的处理(比如将压测产生的数据进行隔离)

ps:和真实请求有差异、写请求需要处理、适合新系统上线或访问量不大的

通过将一台机器的请求复制多份发送到指定的压测机器
适用场景:系统调用量比较小的场景
优点:为了使得压测的请求跟真实的业务请求更加接近,在压测请求的来源方式上,我们尝试从真实的业务流量进行录制和回放,采用请求复制的方式来进行压力测试
缺点:同样也面临着处理写请求脏数据的问题
另外一个缺点复制的请求必须要将响应拦截下来,所以被压测的这台机器需要单独提供,且不能提供正常的服务(不能把响应给到真实的用户了,比如涉及到发短信邮件之类的)

将分布式环境中多台机器的请求转发到一台机器
适用场景:系统调用量比较大的场景
优点:请求的引流转发方式不仅压测结果非常精准、不会产生脏数据、而且操作起来也非常方便快捷,在阿里巴巴也是用的非常广泛的一种单机压测方式,这种方式怎么测试出当前系统最大能抗的流量是多少呢???

修改负载均衡设备的权重,让压测的机器分配更多的请求
适用场景:系统调用量比较大的场景
优点:调整负载均衡方式活的的压测结果非常准确、并且不会产生脏数据

ps:单机压测可以基于上面的4种压测方式基础上,构件一套自动化的压测系统,可以配置定时任务定期对系统进行压测,也可以在任意想压测的时间点手动触发一次压测
在进行压测的同时,实时探测压测机器的系统负载,一旦系统负载达到预设的阈值即立刻停止压测,同时输出一份压测报告
通过单机压测获取的单机服务能力值也是容量规划一个非常重要的参考依据
最小机器数=预估的业务访问量/单机能力最小机器数 = 预估的业务访问量 / 单机能力最小机器数=预估的业务访问量/单机能力

memtier_benchmark可以对Memcached和Redis实例进行基准测试

读场景要注意模拟线上缓存的失效

要考拉压测数据的分布,避免DB单点过热。例如,线上是N个用户,下M个单,压测时不能是1个用户,下M个单

响应时间考虑抛弃平均响应时间,关注tp95

吞吐量要与响应时间、成功率挂钩,

针对全链路压测环境,进行测试,确保各层服务/中间件的隔离、数据/缓存/消息/日志的隔离、业务的mock、各级告警已经生效了,保证压测有效。保障压测安全。

随机文章