性能问题之线程阻塞
定义
在多线程情况下,如果一个线程拥有某个资源的锁,那么这个线程就可以运行资源相关的代码,其他线程就只能等待其执行完毕后,才能继续争夺资源锁,从而运行相关代码。
场景
车票售卖系统,当剩余车票为1张,此时有A/B/C/D四个用户同时来购票,系统开启了四个线程来执行业务操作。
上图中,
首先A线程刚执行了step1;
此时CPU将执行权切换到B线程,B线程顺利执行了step1和step2,此时余票数为0;
这时CPU将执行权又切换到了A,A线程继续执行step2,此时余票数变成了-1,出现了一场业务数据。
上述的情况就是多线程模式下的数据安全问题。
案例分析
某接口压测结果如下:
第一次压测:30线程5分钟
第二次压测:40线程跑5分钟
第三次压测:50线程跑5分钟
从上述3次测试结果来看,CPU利用率不变的情况下,线程增多,TPS不升反降。
重新跑一次50线程跑5分钟,脚本运行过程中获取线程信息:
1、通过jvisualvm查看线程,鲜红色代表阻塞,同时获取线程dump信息
2、直接在服务器上多执行几次jstack,将线程日志下载到本地后查询“BLOCKED”,找到问题代码
注:上述例子中log4j源码中加了锁,将日志级别调整到ERROR级别,重新压测,TPS提高,没有阻塞情况
总结
线程阻塞问题排查流程:
1、做线程dump
2、在dump文件中搜索关键字"BLOCKED"、"TIME_WAITTING",查看每种状态的count数量
3、按照上述关键字搜索,查看跟本系统有关的业务代码堆栈信息
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)