线程信息的作用

JVM由多个线程组成了一个进程,每个线程代表一个操作。线程信息主要用于分析当时整个服务器正在执行什么操作。

线程信息的使用场景

线程信息主要用于分析服务器宕机(因为假如服务器宕机,从线程可能可以看到死锁,某操作一直执行没有完成,如数据库查询语句没有返回)。
或某些操作服务器一直不响应的情况,如保存操作一直没有响应,查询报表没有响应之类的问题都可以通过线程看出来。

怎么打印线程信息

方法1

在系统没有宕机时,可以访问"系统监控"->"线程"获取线程信息

方法2

V62或V72以后的版本也可以访问应用服务器smartbi\mlogs-smartbi\threaddump目录获取最新的线程信息

注:之所以会有上面的线程信息,是因为默认启用自动打印线程信息,可以在系统选项中修改,见下图:

方法3

要求JDK版本为1.6及其以上版本。
1、在运行中打开cmd命令行窗口。
2、在cmd窗口进入JDK的bin目录下,执行jps获取进程信息,此处要保证执行的JDK是服务器使用的JDK。
     如命令行:cd C:\Smartbi_Insight\jdk\bin
                     jps
       
3、获取对应线程号,然后执行jstack +进程号 > 进程号.log 获取线程信息 :Tomcat显示的名称应该是Bootstrap;

4、可以在 C:\Smartbi_Insight\jdk\bin 目录下看到生成的线程文件。

方法4

1、通过CMD命令行窗口进入JDK的bin目录下
2、使用netstat -ano|find "访问的端口号"|find "LISTENING" 获取进程号(注意双引号是必须的)
     如访问smartbi的端口号是18080,则输入命令:netstat -ano|find "18080"|find "LISTENING"

3、再使用jstack 进程号 >进程号.log 获取线程信息,如果提示无法连接到JVM,可以增加-F参数强制生成jstack -F 进程号 >进程号.log
上边截图获取到进程号是7280,可输入命令行:jstack 7280 >7280.log


或者:输入命令行:jstack -F 7280 >test.log

方法5

1、进入jdk/bin,执行jvisualvm.exe

2、找到对应的线程号,然后进入线程 --> 线程 dump

方法6

Lunix下通过ps ef|grep java获取线程号,再通过kill -3 pid获取线程信息

怎么分析线程信息

在线程文件中查找smartbi字样, 查看完整的线程信息分析。

线程的状态有BLOCK,WAITING,RUNNABLE

BLOCK是等待锁的线程(代码里含有synchronized),需要看该线程等待的线程在执行什么操作,如果持有锁的线程处于RUNNABLE则是正常行为(某些情况长时间RUNNABLE也是不正常行为,如执行一个简单sql数据库没有响应),如果处于BLOCk,要继续查询下个锁的进程, 通常就是两种结果RUNNABLE和死锁。

Waiting是等待别人唤醒的线程,代码里主动调用了wait() 引起的, 需要notify()唤醒,在smartbi产品的场景里,主要有池、电子表格报表执行, 比如,数据库连接池满了,新的获取数据库链接的线程会长时间处于waiting状态,直到现有使用连接池的数据库链接关闭,会唤醒其中的waiting线程继续执行,当线程长时间处于waiting状态,可能是需要重点关注分析的(见下文)。

RUNNABLE是正在执行的线程。

有时全部线程都处于RUNNABL状态,需要多次打印比较线程的执行状态, 如果通过这多次打印结果看到某个线程一直执行同一操作,如一直读取socket,一直在删除文件。
一般拿到线程信息,优先关注smartbi的block线程,block线程没问题时,这时通常一个个看,主要是看每个线程在干什么,通过这个干什么判断一些问题,这时候考验对产品的熟悉度。下面是常见的案例:

1.线程等待

      通常lock是synchronized产生的,我们需要查找处于block状态的线程,

      搜索locked <0x00000000eacb6600>(这个代表持有这个锁)
      找到对应的持有锁线程,查看其执行逻辑(这时候靠人为判断逻辑有没有问题)
      "http-bio-8072-exec-9" daemon prio=6 tid=0x0000000010e37800 nid=0x238c waiting on condition [0x000000001485c000]
      java.lang.Thread.State: TIMED_WAITING (parking)
     at sun.misc.Unsafe.park(Native Method)

          附上线程分析的工具ThreadAnalyzer的使用帮助,点击其中的常用工具>ThreadAnalyzer,该工具可以很方便的看出锁等待及死锁问题。

 线程案例

          请使用ThreadAnalyzer工具分下下面两个案例原因,提示:其中一个是卡在数据库连接不返回,另一个主要是集群缓存同步缓慢。

           锁等待线程案例2018-03-31 18_58_30

           集群缓存卡住1608.pid.jstack