也不知道为啥,鬼使神差的登录了我们的宝塔后台
宝塔Linux面板是提升运维效率的服务器管理软件,支持一键LAMP/LNMP/集群/监控/网站/FTP/数据库/JAVA等100多项服务器管理功能。
发现CPU的使用爆满,一下激起了我的好奇心。
赶紧进入服务器执行top命令查看服务器各项指标使用情况。
第一行的进程CPU占用776.6,此时能确定是这个Java服务的问题。
接着使用命令
top -H -p pid
查看49440占用CPU高的线程
top -H -p 49440
此结果忘记截图,下图是网上找的,大概能知道是啥就可以:
此时发现第一个线程占用CPU非常高,我们继续分析一下这个线程为什么占用CPU如此之高。
我们需要转换线程id:
printf "%x\n" 17880
45d8
定位原因:
jstack 49440|grep 45d8 -A 30
发现该线程中存在很多线程状态为WAITING
大致能知道是因为线程阻塞造成的。
继续分析,发现是由于代码里使用的StringBuffer导致线程阻塞,业务场景是,用户登录后需要给用户生成一个Token,使用StringBuffer进行拼接,由于JAVA中StringBuffer使用Synchronized实现线程安全,性能比较低,线程竞争较大的时候效率很低,因此我们不推荐使用StringBuffer。
发现了问题,需要进行处理,我们可以使用StringBuilder进行字符串拼接,安全问题使用ReentrantLock可重入锁来解决。
修改上线,观察一段时间,CPU恢复正常状态
但偶尔出现波峰导致CPU上升到20%作用,但很快就会恢复正常,安心睡觉。