转载

如何做一次完美的压测

压力测试其实有的时候更考验人的经验

与测试相关的指标

  1. qps : 每秒查询数 -> 这个指标一般用在数据库上 , 不过很多人都把这个和TPS混淆,这个知道怎么会是就行了
  2. tps : 每秒内的事务数 -> 执行多组操作的性能 -> 也是数据库的一个指标 , 不过呢我们可以把我们的后台接口操作想象成一个事务 , 所以这个指标是标准的
  3. pv : 只的是调用次数
  4. RT : 接口的响应时间
  5. cpu使用率 : 大家都懂
  6. cpu loading指数 : 这个指标比较重要 , 能反映出cpu当前的"疲劳"程度 , 当前cpu处理任务数量 , 一般最大都要保证内核数量*1.2一下
  7. 内存 : 大家都懂
  8. 出向和入向流量 : 大家都懂

还有两个词 , 低延迟和高吞吐

如何获得指标

使用常用的压测工具都可以 , jmeter等等 , 这类操作工具都会将qps 或者 tps , RT 整理统计出来 , 这里就不展开了

如何真正的把机器的性能压出来,做一次完美的压测

去压测性能的真的是一个技术活 , 是一个慢慢试出来的过程

首先我们要做性能预估

面对一个集群 , 性能如何应该怎么预估呢?

没别的办法 , 看经验 , 靠猜

但是也可以使用一些简单的办法 , 比如

  1. 由小道大 , 逐级测试 -> 用一个小的压力做初次预估 , 慢慢逼近性能极限
  2. 参照物法 , 逐渐逼近 -> 一组内公司内类似规模的系统 , 进行初次预估
  3. 玄学瞎猜 , 慢慢测试 -> 没有任何可以参考的就瞎猜一个吧 , 然后慢慢去寻找

制定压力层级和对应的指标

在压测过程中性能(QPS/TPS)的随着压力的变化曲线应该是一个波浪状的

找出了预估的并发大小之后(一般是一个5的倍数的并发数) , 以这个为基准 , 增加多少并发 , 减少多少并发 , 列成表格 , 注意记录各种性能的指标

比如 :

接口 并发数量 压测时间 tps/qps pv RT(min) RT(max) RT(average) RT(median) cpu loading cpu 使用率
goods_list 10 60s 3000 1w 1ms 30ms 15ms 20ms 6 100%

ps : 这里就有一统计学的东西了 , 比如中位数和平均值 ,其实在压测的时候中位数更能体现出RT这个指标的实际效果

注意 : 这个得出的性能(qps/tps)信息最后至少有一个下降的维度 , 是一个波浪状的效果 , 这样才能找到性能的极限

注意 : 最终性能要使用有效数据 , 如果RT 超过限制或者cpu loading 超过了限制 , 那么这个数据认为不达标 , 但是这个可以用作统计分析

性能瓶颈定位

影响性能的原因有多种 , 不一定真的是系统本身的问题

通过上面的制定压力层级和对应的指标 , 我们已经可以确定了我们当前系统的极限性能了 , 我们不禁想问这些真的是我们的极限性能了吗?

其实我们通过 cpu loading qps tps RT PV 等其实已经能确定当前场景下的一个最佳性能了 , 接写来就需要进行性能问题排查调优

瓶颈排查:

  1. 排查日志 , 找到耗时过长逻辑 , 定位分析 , 比如java 系的系统可以使用 alibaba 开源的在线性能分析工具 arthas
  2. 排查网络问题 : 当确认代码逻辑没有问题的时候 , 网络延迟过高也会影响qps , 比如跨机房调用等 . 这个时候需要找运维同学协助解决 , 做部署迁移 , 搭建专用线路等方法
  3. 最后 cpu瓶颈 : 这个时候只能通过加机器解决

性能调优

这个步骤就很多了, 要针对自己的技术栈进行操作 , 比如 java 可修改jvm参数 , 看一下 jvm GC , 内存状态 , 分别对应的进行一下调优 . ps java事情真多... ...

性能瓶颈定位-其他方面

qps上不去问题可能并不是后台的事情 , 不同类型的系统间的相互调用也可能会导致性能问题

随着现在互联网架构的升级 epoll 模式的广泛应用 ,系统之间的调用也可能成为性能的瓶颈

举个例子

  • 传统java线程体系是一个典型的低延迟系统 , 因为线程模型是独立执行的不会正常理想情况下不会中途终止执行(线程上下文切换) , 所以说一个任务执行完成的时间就是这个任务执行在cpu中的最短时间.
  • golang/nodejs是高吞吐系统 , 应为底层用了epoll 模型使用事件轮询 , 其实本质上是将多个任务分配到一个线程中去执行 , 也就是说一个任务执行完的时间近似等于这一个线程所有任务完成的平均时间 .

上面介绍完了 -> 引出重点 , 上面的两个系统如果java 去调用golang或者nodejs的系统的话 , java就会出现性能问题

因为java 在线程模型下 , 要能保证高的性能必须保证延迟要足够低 , 否则会导致线程过多,线程上下文切换频繁 , 结果拉低整个性能. 但是golang/nodejs 只是保证的吞吐 qps 没有保证延迟RT 所以 , 会导致底层服务性能很好吞吐量高但是上层服务怎么优化都没办法实现高并发.

如何解决 , java 抛弃线程模型使用NIO , 应为针对会联网应用在延迟可控的情况下应该尽可能的追求吞吐量 , 但是java NIO模型需要写异步回调 , 代码很编写这会导致开发效率降低 . 权衡下来 , 只能java增加机器来解决了.

性能瓶颈定位-压测的时候压力机器也要注意 , 有的时候瓶颈可能是压力机器的

如果我们只是使用一台压力机器进行压测是片面的 , 因为网络的开销延迟 ,都能影响到压力机器对测试机器的负载 , 也就是说压力机到了上限但是测试机还没有道

解决方法 , 使用集群进行压力测试

最后

这里只是记录了单个业务的压测方法 , 其实现在架构中还有针对整个调用链路的压测

全链路压测 其实是这种单业务压测的范化场景 , 需要调动各个部门 , 各个系统的开发人员一起做性能压测 , 技术上的操作和单业务压测是类似的 , 只是多了一些 调用链路性能指标 , 各个系统之间调用的性能记录 , 还有一些 故障演练 . 其实全链路更考验我们的组织能力,团队协作和沟通交流能力.

原文  https://segmentfault.com/a/1190000022154799
正文到此结束
Loading...