性能问题之线程阻塞

定义

在多线程情况下,如果一个线程拥有某个资源的锁,那么这个线程就可以运行资源相关的代码,其他线程就只能等待其执行完毕后,才能继续争夺资源锁,从而运行相关代码。

 

场景

车票售卖系统,当剩余车票为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、按照上述关键字搜索,查看跟本系统有关的业务代码堆栈信息
 
 
 
 
posted @ 2022-04-14 22:25  阳光倾林  阅读(524)  评论(0编辑  收藏  举报