线上问题排查

目录

  • top命令
  • 对load的理解
  • load高、cpu高
  • load高、cpu低
  • load高的几种原因总结:
  • RPC问题排查

top命令

top命令是最常见的查看cpu和load的命令,拿我自己虚拟机上装的ubuntu系统执行一下top命令(默认3秒刷1次,-d可指定刷新时间):

线上问题排查_第1张图片

做了一张表格比较详细地解释了每一部分的含义,其中重要属性做了标红加粗:
线上问题排查_第2张图片内存与SWAP输出格式是一样的,因此放在了一起写。

对load的理解

可以使用man uptime命令看一下Linux对于load的解释:
线上问题排查_第3张图片
大致意思就是说,系统load是处于运行状态或者不可中断状态的进程的平均数(标红部分表示被算入load的内容)。一个处于运行状态的进程表示正在使用cpu或者等待使用cpu,一个不可中断状态的进程表示正在等待IO,例如磁盘IO或网络IO。load的平均值通过3个时间间隔来展示,就是我们看到的1分钟、5分钟、15分钟,load值和cpu核数有关,单核cpu的load=1表示系统一直处在负载状态,但是4核cpu的load=1表示系统有75%的空闲。

load这个值,它和请求数没有任何关系,真正和load相关的是工作线程数量,main线程是工作线程、Timer是工作线程、GC线程也是工作线程,load是以线程/进程作为统计指标,无论请求数是多少,最终都需要线程去处理,而工作线程的处理性能直接决定了最终的load值。

load高、cpu高

在一个Java应用中,排查cpu高的思路通常比较简单,有比较固定的做法:

  • ps -ef | grep java、top命令、JPS -lmv,查询Java应用的进程pid
  • top -H -p pid,查询占用cpu最高的线程pid
  • 将10进制的线程pid转成16进制的线程pid,printf “%x\n” tid 例如2000=0x7d0
  • jstack 进程pid | grep -A 20 ‘0x7d0’,查找nid匹配的线程,查看堆栈,定位引起高cpu的原因(-A表示after 20表示20行,也就是打印之后的20行堆栈信息)

实际排查问题的时候jstack建议打印5次至少3次,根据多次的堆栈内容,再结合相关代码段进行分析,定位高cpu出现的原因,高cpu可能是代码段中某个bug导致的而不是堆栈打印出来的那几行导致的。
例如:
线上问题排查_第4张图片
此处的代码问题在于:如果paramMap不为空,但dateParamMap为空的,那么程序就会出现死循环。真是一个大BUG啊!

修改为以下代码:
线上问题排查_第5张图片
cpu高的情况还有一种可能的原因:频繁FullGC,GC线程活动频繁

针对FullGC的问题,排查思路通常为:

  • ps -ef | grep java、top命令、JPS -lmv,查询Java应用的进程pid
  • jstat -gcutil pid 1000 1000,每隔1秒打印一次内存情况共打印1000次,观察老年代(O)、MetaSpace(MU)的内存使用率与FullGC次数
  • 确认有频繁的FullGC的发生,查看GC日志,每个应用GC日志配置的路径不同(添加参数 -XX:+PrintGCDetails)
  • jmap -dump:format=b,file=filename pid,保留现场(也可以用-XX:+HeapDumpOnOutOfMemoryError、 -XX:+HeapDumpBeforeFullGC参数)
  • 重启应用,迅速止血,避免引起更大的线上问题
  • dump出来的内容,结合MAT分析工具分析内存情况,排查FullGC出现的原因

例如:
系统上线不久后,频繁出现内存溢出异常,调大XMX参数,重启应用后还是不起作用。于是用-XX:+HeapDumpOnOutOfMemoryError参数导出堆转储文件,并用Memory Analyzer工具(MAT)分析,通过可视化界面的内存饼状图发现内存大量聚集在一个map对象上,进一步查看map的引用链关系,发现map引用了大量的bitmap图片对象,分析代码发现,这些图片主要用作系统中文档单据的签名图片,系统在启动时将大量的图片放入到map中作为缓存使用,由于没有缓存淘汰机制,这些图片一直占用这大量的内存,最后出现内存溢出异常。
MAT工具分析如下:
线上问题排查_第6张图片
线上问题排查_第7张图片
线上问题排查_第8张图片
解决:用软引用SoftReference与图片对象关联,将软引用放入缓存中。内存不足时,虚拟机自动回收软引用所关联的对象,实现了缓存淘汰。由于缓存失效,所以再次访问时需要从磁盘上加载图片到缓存。

//首先定义一个HashMap,保存软引用对象。
private Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();

//再来定义一个方法,保存Bitmap的软引用到HashMap。
public void addBitmapToCache(String path) {
		// 强引用的Bitmap对象
        Bitmap bitmap = BitmapFactory.decodeFile(path);

        // 软引用的Bitmap对象
        SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap);

        // 添加该对象到Map中使其缓存
        imageCache.put(path, softBitmap);
}
    
    //获取的时候,可以通过SoftReference的get()方法得到Bitmap对象。
    public Bitmap getBitmapByPath(String path) {
		// 从缓存中取软引用的Bitmap对象
        SoftReference<Bitmap> softBitmap = imageCache.get(path);

        // 判断是否存在软引用
        if (softBitmap == null) {
        	return null;
        }

        // 取出Bitmap对象,如果由于内存不足Bitmap被回收,将取得
        Bitmap bitmap = softBitmap.get();
		return bitmap;
}

软引用:只有内存不足时,(软引用关联的对象)才会被回收
弱引用:只要发生gc,(软引用关联的对象)就会被回收,对象生命周期更短

软引用,弱引用使用场景对比:

  • 如果只是想避免OutOfMemory异常的发生,则可以使用软引用。如果对于应用的性能更在意,想尽快回收一些占用内存比较大的对象,则可以使用弱引用。
  • 也可以根据对象是否经常使用来判断。如果该对象可能会经常使用的,就尽量用软引用。如果该对象不被使用的可能性更大些,就可以用弱引用。
  • 另外,和弱引用功能类似的是WeakHashMap。WeakHashMap对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的回收,回收以后,其条目从映射中有效地移除。WeakHashMap使用ReferenceQueue实现的这种机制。使用场景参见https://blog.csdn.net/kaka0509/article/details/73459419

load高、cpu低

在cpu不高的情况下假如load高,大概率IO高才是罪魁祸首
磁盘IO(少数情况):多线程都在读取本地一个超大的文件到内存
网络IO:

  • 从数据库中获取数据(慢查询sql)
  • 从Redis中获取数据(操作bigkey)
  • dubbo等RPC调用响应时间长(具体见后续分析)

load高的几种原因总结:

• 死循环或者不合理的大量循环操作,如果不是循环操作,按照现代cpu的处理速度来说处理一大段代码也就一会会儿的事,基本对能力无消耗
• 频繁的YoungGC
• 频繁的FullGC
• 高磁盘IO
• 高网络IO

RPC问题排查

  • tcpdump抓包,用wireshark分析,查看网络延迟是否严重,是否有tcp重传
  • 查看服务提供者cpu、load,是否飙高,打印线程堆栈,查看有没有死锁、死循环、频繁fullgc等,死锁、死循环直接造成调用超时,fullgc会发生停顿,造成调用耗时较长
  • 方法入参、方法返回值是否很大,影响序列化和网络传输
  • 查看服务提供者业务逻辑是否有DB操作,有的话看是否有慢SQL
  • 查看服务提供者业务逻辑是否有缓存操作,操作redis的bigkey
  • 查看消费者的超时时间设置是否合理,增加超时时间

参考:
https://www.cnblogs.com/xrq730/p/11041741.html
https://blog.csdn.net/puhaiyang/article/details/78663942
https://www.cnblogs.com/dolphin0520/p/3784171.html
https://blog.csdn.net/arui319/article/details/8489451
https://blog.csdn.net/kaka0509/article/details/73459419

你可能感兴趣的:(线上问题排查)