吊打面试官之项目线上问题排查

1、线上常出现的问题

  1. CPU相关问题
  2. 内存相关问题
  3. 磁盘及IO相关问题
  4. 业务代码问题
    推荐使用工具: Arthas 来排查问题

2 、CPU相关问题

      常见原因:频繁 gc,死循环、线程阻塞、io wait…etc

2.1、模拟CPU飙升的场景

public class DemoContrller {

    public static void main(String[] args) {
        cpuReaper();
    }

    /**
     * 模拟 cpu 飙升场景
     * @author wtyicy
     */
    public static void cpuReaper() {
        int num = 0;
        long start = System.currentTimeMillis() / 1000;
        while (true) {
            num = num + 1;
            if (num == Integer.MAX_VALUE) {
                System.out.println("reset");
                num = 0;
            }
            if ((System.currentTimeMillis() / 1000) - start > 1000) {
                return;
            }
        }
    }
}

2.2、排查套路

      如果发现系统变慢边卡,应用响应慢,首先要查的就是CPU使用情况,一般是进程占用CPU过高,英尺需要监测CPU的占用情况,而java应用中与CPU相关的主要是线程的运行,因此具体到java应用,需要监测线程的运行状态,对应就是命令行工具jstack。

# 1、查询CPU占用搞的进程ID(PID)
top -c

# 2、了解此进程的启动参数
ps -ef|grep PID 或者 jinfo -flags PID

# 3、打印线程堆栈信息并输出文件
jstack -l PID > PID.dump

# 4、根据进程查找线程ID(TID)
top -H -p PID

# 5、获取TID的16进制数
print "%x\n" TID

# 6、结合TID和线程堆栈信息文件查找问题
- 可以使用文本工具直接查看呢
- 可以使用 grep TID -A20 PID.dump 来查看
- 需要配合线程状态来检查


3、内存相关问题

  1. java.lang.OutOfMemoryError: Java heap space,堆的内存占用已经达到-Xmx设置的最大值,无法创建新对象,简单的可以考虑通过调整-Xmx参数来解决。
  2. java.lang.OutOfMemoryError: GC Overhead limit exceeded,表示GC一直在执行且java进程运行很慢,通常会抛出此异常,java堆的分配的空间很小以至于新数据无法放到堆中。考虑调整堆大小,如果想关闭此输出,可用参数来关闭-XX:-UseGCOverheadLimit。
  3. java.lang.OutOfMemoryError: Requested array size exceeds VM limit,java应用尝试分配大于堆大小的数组,如堆大小是256M,却要分配512M的数组,则会报错。考虑调整堆大小或者修改代码
  4. java.lang.OutOfMemoryError: Metaspace,当类元数据所需的本机内存量超过时MaxMetaSpaceSize时报出,考虑调整MaxMetaSpaceSize。
  5. java.lang.OutOfMemoryError: request size bytes for reason. Out of swap space?当来自本机堆的分配失败并且本机堆可能接近耗尽时会报此错误,需要查看日志来处理。
  6. java.lang.OutOfMemoryError: Compressed class space,JVM的非堆结构中,类指针存放空间不足,考虑使用CompressedClassSpaceSize来调整。
  7. java.lang.OutOfMemoryError: reason stack_trace_with_native_method,JVM的本地方法区不足,在Java本机接口(JNI)或本机方法中检测到分配失败,需要查找对应堆栈信息来查询。

3.1、模拟OOM堆异常的场景

static final int SIZE=2*1024*1024;
public static void main(String[] a) {
	int[] i = new int[SIZE];
}

3.2、排查套路

      因此需要建议在java应用启动时,添加几个参数,包括-Xloggc:file -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/heapdump.hprof -XX:ErrorFile=logs/java_error_%p.log。这样当发生oom时,可以从dump出来的文件来分析oom的原因

# 1、找到java应用进程(PID)
jps -lvm 或者 top -c

# 2、了解此进程启动参数(特别是-Xms,-Xmx等)
ps -ef|grep  PID 或者 jinfo -flags PID

# 3、 确认内存情况
jmap -heap PID

# 4、 查找占内存的大对象
jmap -histo:live PID 

# 5、 dump出堆文件,以便使用工具分析
jmap -dump:file=./heap.hprof PID

# 6、查看GC变化情况,如下每秒打印一次
jstat -gc PID 1000 

# 7、 结合日志文件出错信息及dump出来的堆文件分析OOM和GC情况
- 内存分配小,适当调整内存
- 对象被频繁创建,且不释放,优化代码
- young gc频率太高,查看-Xmn、-XX:SurvivorRatio等参数设置是否合理

4、磁盘及IO相关问题

4.1、模拟磁盘满的场景

// 往一个满的磁盘写文件
public static void main(String[] a) {
	PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("test.txt"),1500))
}

4.2、排查套路

      java应用运行过程中,会涉及日志产生,对磁盘的读写等操作,也有可能有各种问题,如磁盘不足(日志输出过多)、、磁盘读写IO比较慢、IO过于频繁等。

# 1、查看磁盘容量情况
df -h

# 2、 查看文件大小和目录大小
ls -l 或者直接ll
du -h --max-depth=1

# 3、 查看IO情况,找到IO读写频繁的进程PID
iotop -d 1 # 1秒打印一次
或者
iostat -d -x -k 1 #1秒打印一次

# 4、 使用stack打印线程堆栈信息,排查IO相关代码

# 5、 有时候若想测试磁盘的读写速度(特别是虚拟机),可以使用dd
# 示例:测数据卷挂载目录的纯写速度
dd if=/dev/zero of=/数据卷目录/test.iso bs=8k count=1000000

5、业务代码问题

5.1、模拟ArithmeticException的场景

public static void main(String[] a) {
	int i = 1/0}

6.2、排查套路

      主要是涉及到代码逻辑层面的,主要是查询日志输出,方法是否按正确的逻辑执行。

# (1) 实时日志输出查询
tail -fn 100 log_file

# (2) 根据日志输出的关键字来定位问题
grep keyWord log_file # 关键字所在行
grep -C n keyWord log_file # 关键字所在前后n行

# (3) 日志文件使用可视化文本工具分析(notepad++,sublime,大文件查看如EmEditor)

# (4) 使用线上工具直接检测方法的参数、返回值,异常情况等等,如Btrace,arthas等。

6、往期佳文

6.1、面试系列

1、吊打面试官之一面自我介绍
2、吊打面试官之一面项目介绍
3、吊打面试官之一面系统架构设计
4、吊打面试官之一面你负责哪一块

······持续更新中······


6.2、技术系列

1、吊打面试官之分布式会话
2、吊打面试官之分布式锁
3、吊打面试官之乐观锁
4、吊打面试官之幂等性问题
5、吊打面试关之分布式事务

······持续更新中······

6.3、源码系列

1、源码分析之SpringBoot启动流程原理
2、源码分析之SpringBoot自动装配原理

······持续更新中······


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值