java 优化线程_JAVA优化篇 如何从茫茫日志中找到运行缓慢的线程

引入

JAVA提供了一些分析DUMP的工具,比如jmap,visualvm 等

JAVA还有寻找线程状态的工具,jstack等

数据库也有检查连接数,连接状态的命令,status,processlist等

代码中也可以添加一些时间的信息,对比信息发现可优化的地方

但这些都不是今天要记录的内容,今天要做的是使用一个比较暴力的方式查找出高并发模式下运行缓慢的线程

正文

写高并发的时候经常会遇到的问题:

单独观察每个分支线程或者主线程时,都执行地非常快,但是总体上运行的TPS却并不高,没有达到期望的值

更换环境,或者调大运行内存和CPU后,情况仍然不见好转

这时候有个办法是,找出每个线程的运行过程,寻找出耗时较大的代码段,再对代码进行分析

脚本我已经写好了:

364330e182155d8ef5433af926c4f2f68a8.jpg

9501962d08d69f5ce070c1fcf9241692521.jpg

#!/bin/bash

parseLog(){

##初始值

upLine="blank"last_time_pre="blank"last_time_post="blank"

cat "$1" | whileread linedotime_pre=`echo "$line" | awk '{print$1}'`

time_post=`echo "$line" | awk '{print$2}'`if [[ `echo "$time_post" | grep ":"` != ""]]then

if [[ "$upLine" == "blank"]]thenupLine=${line}

last_time_pre=`echo "$line" | awk '{print$1}'`

last_time_post=`echo "$line" | awk '{print$2}'`

total2="$last_time_pre""$last_time_post"last_time_pre=`date +%s -d "$total2"`

last_time_pre=`expr "$last_time_pre" \* 1000`

last_time_post=`echo ${last_time_post:9:3}`elsetotal="$time_pre""$time_post"time_pre=`date +%s -d "$total"`

time_pre=`expr "$time_pre" \* 1000`

time_post=`echo ${time_post:9:3}`

time_end=`expr "$time_pre" + "$time_post"`

time_begin=`expr "$last_time_pre" + "$last_time_post" + "$2"`

last_time_pre=${time_pre}

last_time_post=${time_post}if [[ "$time_end" -gt "$time_begin"]]then

echo ${upLine} >>result.logecho ${line} >>result.logfiupLine=${line}fi

fi

done}if [[ ! -n "$1" ]] || [[ ! -n "$2" ]] || [[ ! -n "$3"]]then

echo [log file] [interval millis] [key words]

exitfi

awk '{num[$4]++}

END{for(k in num)print k,"----",num[k]|"sort -k 3 -rn"}'"$1" |

head -n 15 | awk '{str[$1]++} END{for (s in str)print s}'| grep "$3" >thread.log

##对上述输出的每一个线程做分析处理,调用parseLogcat thread.log | whileread linedo

grep "\""${line}"\"" "$1" >temp.log

parseLog temp.log $2

doneexit

View Code

这个脚本有个基础条件是,分析的日志必须得是按照一定规范输出的日志,输出字段中带有时间和线程名

脚本传参:

a8c9d2fca8052cc1534874074aa57046.png

获得可以分析的所有线程,按照数量排序,并只获得前15个

0526355e34bfc83f93b9edc0fef0fa0a.png

接下来对每一个过滤出来的线程做分析处理

75fbcf2bb8784d4f24adfb981921aa1c.png

最后就是分析日志的方法了

主要思路是,用下一行的时间减去上一行的时间,如果超过给定的值,就将两行都输出到指定文件。

813fb765245c670bd8b9f654e3b32824.png

执行效果:

[utap@host145 logs]$ sh pick_thread.sh bb.log 1timer

timerQ_3-service-#146]

[utap@host145 logs]$catresult.log2019-11-05 00:02:00.371 [DEBUG] [TaskRule:405][printExpr] [timerQ_3-service-#146] [100000000004] - TaskRule printExpr i-j=2-0, expr[i].elementAt(j).m_min=0, m_max=9999

2019-11-05 00:02:00.373 [DEBUG] [TaskRule:405][printExpr] [timerQ_3-service-#146] [100000000004] - TaskRule printExpr i-j=3-0, expr[i].elementAt(j).m_min=0, m_max=9999^C

方便再次使用到吧,地址在 https://github.com/garfieldcgf/notes/tree/master/operations/bin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值