Java 应用压测性能问题定位经验分享

发表于:2023-1-05 10:21

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:凡勇    来源:阿里云云栖号

  什么是压测
  压测,即压力测试,是确立系统稳定性的一种测试方法,通常在系统正常运作范围之外进行,以考察其功能极限和和可能存在的隐患。
  压测主要用于检测服务器的承受能力,包括用户承受能力,即多少用户同时使用系统时基本不影响质量、流量承受等。另外,通过诸如疲劳测试还能发现系统一些稳定性的问题,比如是否存在连接池中的连接被耗尽,内存被耗尽,线程池被耗尽,这些只能通过疲劳测试来进行发现定位。
  为什么要压测
  压测的目的就是通过模拟真实用户的行为,测算出机器的性能(单台机器的 QPS、TPS),从而推算出系统在承受指定用户数(100 W)时,需要多少机器能支撑得住。因此在进行压测时一定要事先设定压测目标值,这个值不能太小,也不能太大,按照目前业务预估的增长量来做一个合理的评估。压测是在上线前为了应对未来可能达到的用户数量的一次预估(提前演练),压测以后通过优化程序的性能或准备充足的机器,来保证用户的体验。压测还能探测应用系统在出现交易洪峰时稳定性情况,以及可能出现的一些问题,发现应用系统薄弱一环,从而更有针对性地进行加强。
  压测
  这几种测试可以穿插进行,一般会在压力测试性能指标达标后,再安排耐久性测试。
  压测名词解释
  常见的压测工具
  ab
  ApacheBench 是 Apache 服务器自带的一个 web 压力测试工具,简称 ab。ab 又是一个命令行工具,对发起负载的本机要求很低,根据 ab 命令可以创建很多的并发访问线程,模拟多个访问者同时对某一 URL 地址进行访问,因此可以用来测试目标服务器的负载压力。总的来说 ab 工具小巧简单,上手学习较快,可以提供需要的基本性能指标,但是没有图形化结果,不能监控。
  Jmeter
  Apache JMeter 是 Apache 组织开发的基于 Java 的压力测试工具。用于对软件做压力测试,它最初被设计用于 Web 应用测试,但后来扩展到其他测试领域。
  JMeter 能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。
  JMeter 的功能过于强大,这里暂时不介绍用法,可以查询相关文档使用(参考文献中有推荐的教程文档)
  LoadRunner
  LoadRunner 是 HP(Mercury)公司出品的一个性能测试工具,功能非常强大,很多企业级客户都在使用,具体请参考官网链接。
  阿里云PTS
  性能测试 PTS(Performance Testing Service)是一款性能测试工具。支持按需发起压测任务,可提供百万并发、千万 TPS 流量发起能力,100% 兼容 JMeter。提供的场景编排、API 调试、流量定制、流量录制等功能,可快速创建业务压测脚本,精准模拟不同量级用户访问业务系统,帮助业务快速提升系统性能和稳定性。
  作为阿里内部使用多年的性能测试工具,PTS 具备如下特性:
  1、免运维、开箱即用。SaaS化施压、最大支持百万级并发、千万级TPS流量自助发起能力。
  2、支持多协议HTTP1.1/HTTP2/JDBC/MQTT/Kafka/RokectMq/Redis/Websocket/RMTP/HLS/TCP/UDP/SpringCloud/Dubbo/Grpc 等主流协议。
  3、支持流量定制。全球施压地域定制/运营商流量定制/IPv6 流量定制。
  4、稳定、安全。阿里自研引擎、多年双十一场景打磨、支持 VPC 网络压测。
  5、性能压测一站式解决方案。** 0 编码构建复杂压测场景,覆盖压测场景构建、压测模型设定、发起压力、分析定位问题、出压测报告完整的压测生命周期。
  6、100% 兼容开源 JMeter。
  7、提供安全、无侵入的生产环境写压测解决方案。
  压测工具的比较
  如何选择压测工具
  这个世界上没有最好的工具,只有最适合的工具,工具千千万,选择一款适合你的才是最重要的,在实际使用中有各种场景,读者可以结合压测步骤来确定适合自己的工具:
  1. 确定性能压测目标:性能压测目标可能源于项目计划、业务方需求等
  2. 确定性能压测环境:为了尽可能发挥性能压测作用,性能压测环境应当尽可能同线上环境一致
  3. 确定性能压测通过标准:针对性能压测目标以及选取的性能压测环境,制定性能压测通过标准,对于不同于线上环境的性能压测环境,通过标准也应当适度放宽
  4. 设计性能压测:编排压测链路,构造性能压测数据,尽可能模拟真实的请求链路以及请求负载
  5. 执行性能压测:借助性能压测工具,按照设计执行性能压测
  6. 分析性能压测结果报告:分析解读性能压测结果报告,判定性能压测是否达到预期目标,若不满足,要基于性能压测结果报告分析原因
  由上述步骤可知,一次成功的性能压测涉及到多个环节,从场景设计到施压再到分析,缺一不可。工欲善其事,必先利其器,而一款合适的性能工具意味着我们能够在尽可能短的时间内完成一次合理的性能压测,达到事半功倍的效果。
  其他问题案例
  这类问题在发生的时候,JVM 表现得静如止水,CPU 和内存的使用都在正常水位,但是交易就是缓慢,对于这一类问题可以参考 CPU 冲高类问题来进行解决,通过使用线程转储文件或者使用JFR来录制一段 JVM 运行记录。这类问题大概率的原因是由于大部分线程卡在某个 IO 或者被某个锁个 Block 住了,下面也带来一个真实的案例。
  案例一
  某金融保险头部客户,反应某个交易非常缓慢,经常响应时间在 10S 以上,应用部署在公有云的容器上,容器规格为 2C4G,数据库是 OceanBase。问题每次都能重现,通过分布式链路工具只能定位到在某个服务上面慢,并不能精确定是卡在哪个方法上面。在交易缓慢期间,通过 top、vmstat 命令查看 OS 的状态,CPU 和内存资源都在正常水位。因此,需要看在交易期间的线程的状态。在交易执行缓慢期间,将交易的线程给转储出来,如图 29 所示,可以定位相应的线程卡在哪个方法上面,案例中的线程卡在了执行 socket 读数据阶段,从堆栈可以断定是卡在了读数据库上面了。如果这个方法依然不好用,那么还可以借助抓包方式来进行定位。
图 29 交易被 hang 住示例图
  案例二
  某金融银行客户压测过程中发现 TPS 上不去,10TPS 不到,响应时间更是高到令人发指,在经过一段时间的培训赋能和磨合,该客户已经具备些性能定位的能力。给反馈的信息是 SQL 执行时间、CPU 和内存使用一切正常,客户打了一份线程转储文件,发现大多数线程都卡在了使用 RedissionLock 的分布式锁上面,如图 30 所示,后经查是客户没有合理使用分布式锁导致的问题,解决后,TPS 翻了 20 倍。
图 30 分布式锁使用不当导致的问题示例
  这两个案例其实都不算复杂,也很容易进行排查,放到这里只是想重述一下排查这类问题的一个整体的思路和方法。如果交易缓慢且资源使用都正常,可以通过分析线程转储文件或者 JFR 文件来定位问题,这类问题一般是由于 IO 存在瓶颈,又或者被锁 Block 住的原因导致的。
  总结
  问题千千万,但只要修练了足够深厚的内功,形成一套属于自己的排查问题思路和打法,再加上一套支撑问题排查的工具,凭借已有的经验还有偶发到来的那一丝丝灵感,相信所有的问题都会迎刃而解。
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号