说到性能测试, 我们到底是想谈论什么?
任何做产品的, 都希望自己家的产品, 品质优, 性能好, 服务海量用户, 还不出问题.
任何使用产品的, 都喜欢自己购买的产品功能全, 性能优, 不花一分冤枉钱.
不过理想很丰满, 现实很骨感. 实际产品的性能与开发周期, 部署方式, 软硬件性能等都息息相关. 所以真正提到做性能测试的场景, 多数是为满足特定需求而进行的度量或调优.
比如:
针对交付客户的软硬件环境, 提供性能测试报告, 证明对客户需求的满足
针对特定的性能瓶颈, 进行针对性测试, 为问题定位提供帮助
重大功能迭代, 架构设计上线前的性能评估
所有的这些场景, 都隐含着对性能测试目标的确认, 这一点非常重要. 因为如果没有明确的测试目标, 为了做而做, 多数情况是没有价值的, 浪费精力.
而性能测试的目标一般是期望支持的目标用户数量, 负载, QPS 等等, 这些信息一般可以从业务负责人或者产品经理处获得. 当然如果有实际的业务数据支持, 也可以据此分析得出. 所以在开展性能测试之前, 一定要先搞清楚测试目标.
目标明确之后, 如何开展性能测试?
有了性能测试目标, 之后还需要进一步拆解, 做到具体可执行. 根据经验, 个人认为性能测试的执行, 最终会落地到以下两个场景:
在特定硬件条件, 特定部署架构下, 测试系统的最大性能表现
在相同场景, 相同硬件配置下, 与竞品比较, 与过往分析, 总结出优劣
不同的目的, 做事的方式也不一样.
第一类场景, 因为结果的不确定性, 测试时需要不断的探索测试矩阵, 找出尽可能优的结果.
第二类场景, 首先需要理清楚, 业界同类产品, 到底比的是什么, 相应的测试工具是什么, 测试方法是什么. 总之要在公平公正的条件下, 遵循业界标准, 得出测试结果, 给出结论.
所有的性能测试场景, 都需要有明确的分析与结论, 以支持上述两个场景下的目的达成. 测试场景要贴近实际的目标场景, 测试数据要贴近实际的业务数据, 最好就用目标业务场景下的数据来进行性能测试.
服务端性能测试到底要看哪些指标?
不同的领域, 业务形态, 可能关注的性能指标是不一样的, 所以为了表述精确, 我们这里只谈服务端的性能测试指标.
一般我们会用以下指标来衡量被测业务: QPS, 响应时间(Latency), 成功率, 吞吐率, 以及服务端的资源利用率(CPU/Memory/IOPS / 句柄等).
不过, 这里有一些常识需要明确:
响应时间不要用平均值, 要用百分值. 比如常见的, 98 值 (98th percentile) 表示.
成功率是性能数据采集标准的前提, 在成功率不足的情况下, 其他的性能数据是没意义的(当然这时候可以基于失败请求来分析性能瓶颈).
单独说 QPS 不够精确, 而应结合响应时间综合来看. 比如 "在响应时间 TP98 都小于 100ms 情况下, 系统可以达到 10000qps" 这才有意义.
性能测试一定要持续一定时间, 在确保被测业务稳定的情况下, 测出的数据才有意义.
要多体会下这些常识, 实战中很多新手对这块理解不深, 导致有时出的性能数据基本是无效的.
为什么性能测试报告一定要给出明确的软硬件配置, 以及部署方式?
前面说到, 性能数据是与软件版本, 硬件配置, 部署方式等息息相关的. 每一项指标的不同, 得出的数据可能是天差万别. 所以在做性能测试时, 一定要明确这些基础前置条件, 且在后期的性能测试报告中, 清晰的说明.
jmeter, ab, wrk, lotust, k6 这么多性能测试工具, 我应该选择哪个?
业界性能测试数据工具非常多, 不过适用的场景, 以及各自特点会有不同. 所以针对不同的性能测试需求, 应当选择合适的性能工具. 比如:
jmeter: 主要提供图形化操作以及录制功能, 入门简单, 功能也较强大. 缺点是需要额外安装.
ab(apech benchmark): 简单好用, 且一般系统内置了, 应对简单场景已足够
lotust: 简单好用, 支持 python 编写自定义脚本, 支持多 worker, 图形化界面汇总性能数据.
这里不一一介绍工具, 大家有兴趣的都可以自行去网上搜索.
其实笔者在实践过程中发现, 其实绝大多数性能测试场景, 都需要编码实现. 所以如何优雅的结合现有的测试代码, 环境, 以及基础设施, 来方便的进行性能测试反而是个可以考量的点.
笔者比较认可 Go+Prometheus+Kubernetes 的模式. 首先 go 语言因其独有的并发模式, 上手简单等特点, 在云服务, 服务端程序领域使用已经非常广了, 采用其写脚本, 也许与被测程序天然紧密结合. 且服务端程序要想很好的运维, 必然有一套完整的监控告警体系, 而 Prometheus 基本是其中热度最高的, 使用范围最广的, 同时我们也可以将测试程序性能数据打点到 Prometheus, 这样在计算 QPS, 成功率等指标上, 非常方便.
另外大家知道, 在性能测试时, 多数需要不断的调整 metrix, 比如并发数, worker 数量等, 来探测系统的性能表现, 这时候如果将测试程序跑在 Kubernetes 上, 就可以借助其能力, 比如 Deployment, 灵活的部署和水平扩展, 体验相当优雅.
单机 10000 并发为什么可能不靠谱?
我们知道使用 goroutine, 可以瞬间开很多并发, 非常好用. 于是可能就会有同学觉得用它做性能测试很方便, 直接写个脚本, 起超多的并发, 去做性能测试. 但这样真的靠谱吗?
虽然 go 语言的并发, 通过 P,G,M 模型, 在调度 goroutine 时, 比较高效, 但无论如何, 任何的程序执行, 最终消耗的都是系统资源, 测试脚本也同样. 所以单机上执行的并发效果, 最终会受限于, 你脚本的复杂程序, 也就是对 CPU,IO, 网络等系统资源的消耗. 所以, 并不是并发越多越好, 一定是基于实际环境, 通过不断调节并发数量, worker 数量等, 来达到最佳姿势.
构建业务性能数据的持续可观测性对产品质量意义重大
一次专项性的性能分析, 可以观察当前业务的性能表现, 进一步的分析性能瓶颈, 为之后的改进提供帮助, 意义挺大. 但只这样可能不够全面, 因为指不定的某次迭代, 句柄没关, goutinue 泄露, 就会造成性能问题, 如果我们没有常态化的检测手段, 等上线后才发现, 很明显不是我们想看到的.
所以更优雅的做法是, 将性能测试常态化的持续运营, 甚至可以做到每次 PR 触发, 都自动执行性能测试, 检测性能问题.
To-Be-Continued
性能测试对保障产品质量, 提升用户体验意义重大. 笔者这里只罗列了一些个人在实际工作中看的问题, 以及一些体会, 可能不全面. 所以如果您有问题, 欢迎抛出来, 共同探讨.
参考资料
- https://coolshell.cn/articles/17381.html
- https://www.dynatrace.com/news/blog/why-averages-suck-and-percentiles-are-great/
- https://automationrhapsody.com/how-to-do-proper-performance-testing/
- Contact me ?
- Email: jinsdu@outlook.com
- Blog: http://www.cnblogs.com/jinsdu/
- GitHub: https://github.com/CarlJi
来源: https://www.cnblogs.com/jinsdu/p/10646278.html