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

Wesley13
• 阅读 748

引入

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

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

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

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

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

正文

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

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

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

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

  脚本我已经写好了:

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

#!/bin/bash
 parseLog(){
    ##初始值
    upLine="blank"
    last_time_pre="blank"
    last_time_post="blank"
    cat "$1" | while read line
        do
          time_pre=`echo "$line" | awk '{print$1}'`
          time_post=`echo "$line" | awk '{print$2}'`
          if [[ `echo "$time_post" | grep ":"` != "" ]]
            then
            if [[ "$upLine" == "blank" ]]
            then
              upLine=${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}`
            else
              total="$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.log
                    echo ${line} >> result.log
              fi
              upLine=${line}
            fi
          fi
        done
}


if [[ ! -n "$1" ]] || [[ ! -n "$2" ]] || [[ ! -n "$3" ]]
  then
    echo [log file] [interval millis] [key words]
    exit
fi


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


##对上述输出的每一个线程做分析处理,调用parseLog
cat thread.log | while read line
    do
      grep "\""${line}"\""  "$1" > temp.log
      parseLog temp.log $2
    done
exit

View Code

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

脚本传参:

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

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

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

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

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

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

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

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

  执行效果:

[utap@host145 logs]$ sh pick_thread.sh bb.log 1 timer
timerQ_3-service-#146]
[utap@host145 logs]$ cat result.log 
2019-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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这