zoukankan      html  css  js  c++  java
  • 线上性能问题初步排查方法

    引言

    有时候有很多问题只有在线上或者预发环境才能发现,而线上又不能Debug,所以线上问题定位就只能看日志,系统状态和Dump线程,本文只是简单的介绍一些常用的工具,帮助定位线上问题。

    问题定位

    1: 首先使用TOP命令查看每个进程的情况,显示如下:

    我们的程序是Java应用,所以只需要关注COMMAND是Java的性能数据,COMMAND表示启动当前进程的命令,在Java进程这一行里可以看到CPU利用率是300%,不用担心,这个是当前机器所有核加在一起的CPU利用率。

    2: 再使用Top的交互命令数字1查看每个CPU的性能数据。

    命令行显示了CPU4,说明这是一个5核的虚拟机,平均每个CPU利用率在60%以上。如果这里显示CPU利用率100%,则很有可能程序里写了一个死循环。这些参数的含义,可以对比下表:

    3: 使用Top的交互命令H查看每个线程的性能信息。

    在这里可能会出现三种情况:
    1. 如果是第一种情况,也有可能是GC造成,我们可以用jstat命令看下GC情况,看看是不是因为持久代或年老代满了,产生Full GC,导致CPU利用率持续飙高,命令如下。
      我们还可以把线程Dump下来,看看究竟是哪个线程,执行什么代码造成的CPU利用率高。执行以下命令,把线程dump到文件dump17里。
      sudo -u admin /opt/java/bin/jstack  31177 > /home/tengfei.fangtf/dump17
      

      dump出来内容的类似下面这段:

      "http-0.0.0.0-7001-97" daemon prio=10 tid=0x000000004f6a8000 nid=0x555e in Object.wait() [0x0000000052423000]
         java.lang.Thread.State: WAITING (on object monitor)
              at java.lang.Object.wait(Native Method)
              - waiting on  (a org.apache.tomcat.util.net.AprEndpoint$Worker)
              at java.lang.Object.wait(Object.java:485)
              at org.apache.tomcat.util.net.AprEndpoint$Worker.await(AprEndpoint.java:1464)
              - locked  (a org.apache.tomcat.util.net.AprEndpoint$Worker)
              at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1489)
              at java.lang.Thread.run(Thread.java:662)
      

      dump出来的线程ID(nid)是十六进制的,而我们用TOP命令看到的线程ID是10进制的,所以我们要printf命令转换一下进制。然后用16进制的ID去dump里找到对应的线程。

      优化实战

      1:查看下TCP连接状态,建立了800多个连接,需要尽量降低ESTABLISHED。

      2:用jstack dump看看这些线程都在做什么。
      3:统计下所有线程分别处于什么状态,发现大量线程处于WAITING(onobjectmonitor)状态
      4:查看处于WAITING(onobjectmonitor)的线程信息,主要是jboss的工作线程在await。
      "http-0.0.0.0-7001-97" daemon prio=10 tid=0x000000004f6a8000 nid=0x555e in Object.wait() [0x0000000052423000]
       java.lang.Thread.State: WAITING (on object monitor)
       at java.lang.Object.wait(Native Method)
       - waiting on <0x00000007969b2280> (a org.apache.tomcat.util.net.AprEndpoint$Worker)
       at java.lang.Object.wait(Object.java:485)
       at org.apache.tomcat.util.net.AprEndpoint$Worker.await(AprEndpoint.java:1464)
       - locked <0x00000007969b2280> (a org.apache.tomcat.util.net.AprEndpoint$Worker)
       at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1489)
       at java.lang.Thread.run(Thread.java:662)

      5:找到jboss的线程配置信息,将maxThreads降低到100

      6:重启jboss,再dump线程信息,然后统计,WAITING(onobjectmonitor)的线程减少了170。

      其他命令
      • 查看CPU信息 cat /proc/cpuinfo
      • 查看内存信息 cat /proc/meminfo
      • 查看Java线程数 ps -eLf | grep java -c
      • 查看linux系统里打开文件描述符的最大值 ulimit -u
      • 找到日志里TOP10的异常:grep ‘Exception’ /home/admin/logs/XX.log |awk -F':|,’ ‘{print $2}’|sort |uniq -c |sort -nr|head -10,找到之后可以再用-A 2 -B 2,看定位出日志的前面2行和后面两行。
  • 相关阅读:
    Python网络协议(osi七层协议)
    Python面向对象之反射,双下方法
    Python类的成员
    Python异常处理
    mysql 索引 慢查询优化 && 数据库性能优化
    数据库(视图、事务、存储过程、函数) && 数据库备份
    mysql数据库连接模块 pymysql && sql注入
    主线程与子线程的关系
    socket 编程实例 基于线程池实现服务端并发
    日常迷惑积累
  • 原文地址:https://www.cnblogs.com/harveylv/p/6829268.html
Copyright © 2011-2022 走看看