线上出现问题了你有思路解决吗


线上出现问题了你有思路解决吗

1. 线上服务器CPU使用率达到100%,如何排查、定位与解决呢

面试官通过这个问题来试探面试者,有没有真实的玩过线上的机器

导致CPU过高的一般原因

  1. 无线循环,例如递归调用等(可以整个sleep)
  2. 频繁GC(内存分配过快,导致区域很快就满了)
  3. 频繁创建新对象(可以考虑使用单例)
  4. 错误姿势的使用序列化和反序列化类库
  5. 正则表达式
  6. 线程上下文频繁切换

解决方法思路

  1. 使用Linux命令 top 到CPU占用最高的进程A pid1
  2. 再使用 top -Hp 拿到指定进程占用最高的线程 pid2
  3. 使用 printf %x pid2 将10进制线程号转换成16进制 8ccc
  4. 通过 jstack pid1 > dump.txt 获取进程A的堆栈快照
  5. 使用 cat dump.txt | grep -A 30 8ccc 根据16进制信息筛查出有问题的代码(往下展示30行)
  6. 排查代码中的问题并修复

2. 线上机器的一个进程使用kill命令无法杀死怎么办?

kill进程如果死活杀不死,那么这个进程会进入 zombie(僵尸) 状态,也就是一个僵尸进程,这是因为 子进程释放了资源,但是没有经过父进程的确认

解决方法思路

  1. 使用Linux命令 ps aux 查看 stat ,如果对应这一栏值是 Z ,那么说明是僵尸进程
  2. 使用 ps -ef | grep 僵尸进程id 可以找到 父进程id
  3. 使用 kill 杀死父进程即可

3. 磁盘空间快满了,不影响服务的情况下如何解决?

解决方法思路

  1. 使用Linux命令 df -h 查看磁盘使用率情况
  2. 可以通过删除一些年份比较久的日志文件来释放空间。(一般可以通过 crontab定时任务 来每天定时清理一些日志文件,保证空间富余)
  3. 如果不是日志文件导致,就通过 find \ -size +100M | xargs ls -lh (查询根目录下所有大于100M的文件)
  4. 如果没找到大文件,可以查询占据磁盘空间大的目录,看看各个目录里是否有大量的小文件, du -h > fs_du.log

4. 线上发生 java.lang.OutOfMemoryError Java heap space 堆内存溢出怎么办?

堆内存溢出的原因及解决思路

  1. 内存泄漏:找到堆栈引用链,查出哪个对象没有被回收导致内存泄漏(找到泄漏对象的创建位置)
  2. 非内存泄漏:考虑调大JVM参数的xms xmx最大\小堆内存,为应用分配更多的堆内存;检查代码,排除有些对象生命周期是否太长了,又或者存储结构不合理(有时换个方式存储对象可以节省很多内存)

现实可能发生堆内存溢出的场景

  1. 数据库过多数据返回给服务端,导致内存溢出:
  2. 根据某个分类搜索商品列表(分页),如果这个分类的商品特别多,并且pageSize没有设置限制,被恶意攻击时,会一下子就把内存打崩

举个🌰说明

\**
 * 使用该选项运行:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
      使用最小\最大堆内存都为20m 并且在堆内存溢出时做一次堆dump
 *\
public class HeapOOMTest {
    private List<String> oomList = new ArrayList<>();

    public static void main(String[] args) {
        HeapOOMTest oomTest = new HeapOOMTest();
        while (true) {
            oomTest.oomList.add(UUID.randomUUID().toString());
        }
    }
}

按照配置运行代码,会发生堆内存溢出。

在实际项目中,堆内存溢出可能会导致进程崩溃,极端场景下进程可能直接就挂掉了,不会打印日志

项目根目录中,会生成dump文件,例如 java_pid15468.hprof

分析dump文件

  1. MAT
  2. VisualVM
  3. PerfMa

具体操作查看本人在有道云做的笔记

实战:堆内存溢出【java.lang.OutOfMemoryError Java heap space】

也可以查看以下文章

实战:OOM 后我如何分析解决的 | PerfMa应用性能技术社区

栈内存溢出:可能由 递归创建过多栈帧 导致栈内存溢出
方法区内存溢出:可能由 常量占据内存过多 导致元空间内存不足

5. 如果一个项目越跑越慢,你觉得可能是因为什么?

  1. 垃圾收集非常频繁,stop the world时间越来越长,导致项目执行越来越慢
  2. 数据库数据量变大(慢SQL优化或者分库分表来解决)
  3. Code Cache默认的240M代码缓存区满了。未满时,代码以编译的方式执行,如果满了,代码会以解释的方式执行,执行速度上比编译执行慢了一个数量级,严重影响项目性能
  4. 线程争抢过于激烈,导致代码争抢不到CPU时间片去执行任务
  5. 操作系统问题则重启大法好

代码缓存区相关知识点:实战:代码缓存区域满

可以通过 skywalking 来预防和辅助分析问题


评论
  目录