大厂面试官:实习期间有没有参与处理过线上问题?拿走直接抄答案!

所有 Java 服务的线上问题从系统表象来看归结起来总共有四方面:CPU、内存、磁盘、网络。例如 CPU 使用率峰值突然飚高、内存溢出 (泄露)、磁盘满了、网络流量异常、FullGC等等问题。

本文从以下四个角度,去分析如何排查线上问题,如果你也遇见过上面的这些问题,却无从下手相信你看完这篇文章,能够掌握线上问题的排查思路与工具方法,方便你遇到线上问题时,心中有数,不慌不忙,赶紧mark起来吧。

  1. CPU,CPU使用率飙升,如何定位
  2. 内存,内存溢出、垃圾回收的问题排查思路与工具
  3. IO,IO异常时,如何定位
  4. 网络,网络卡顿,网络不通的排查思路

先说结论,大部分工程师也许没有全面的性能问题诊断机会,解决线上问题,也没有所谓的银弹。多实践,多学习底层原理,才能让你拥有更丰富的经验。

使用到的工具

系统Mac OS 14.3 Jprofiler 14.0版本

问题定位

CPU

CPU 是系统重要的监控指标,能够分析系统的整体运行状况。监控指标一般包括运行队列、CPU 使用率和上下文切换等。

top 命令显示了各个进程 CPU 使用情况 , 一般 CPU 使用率从高到低排序展示输出。其中 Load Average 显示最近 1 分钟、5 分钟和 15 分钟的系统平均负载,上图各值为0.11,0.08,0.05

我们一般会关注 CPU 使用率最高的进程,正常情况下就是我们的应用主进程。第七行以下:各进程的状态监控。

关于线上的CPU问题,常见的问题有以下三种

  • CPU突然飙升
  • CPU使用居高不下
  • cpu占用高

往往都是业务逻辑问题导致的,比如死循环、频繁gc或者上下文切换过多。线上问题排查,为了能够保持现场情况,一般我们直接登陆机器,使用命令行进行排查。

当然,为了方便你更好的理解,我也提供了一个简单的示例代码,如下所示。

public class CpuTests {

    public static void busyThread(){
        Thread thread = new Thread(() -> {
            while (true){

            }
        },"*busyThread");
        thread.start();
    }

    public static void lockThread(Object lock){
        Thread thread = new Thread(() -> {
            synchronized (lock){
                try {
                    lock.wait();
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        },"lockThread");
        thread.start();
    }
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader
                = new BufferedReader(new InputStreamReader(System.in));
        bufferedReader.readLine();
        busyThread();
        bufferedReader.readLine();
        lockThread(new Object());
    }
}

命令行排查

我们使用top -H -p pid来找到cpu使用率比较高的一些线程

占用率最高的线程 ID 为 1586480,将其转换为 16 进制形式 (因为 java native 线程以 16 进制形式输出)printf '%x\n' 1586480pid得到nid

接着直接在jstack中找到相应的堆栈信息jstack pid |grep 'nid' -C5

注:因为我本地环境是Mac Os,且我们上面的例子比较简单,我们直接使用jstack 也可以看到线程情况

可视化工具

当然,也可以使用工具,直接可视化的查看线程情况

通过Jprofiler的cpu负载,我们可以看到cpu负载一直巨高不下,如果排除了流量上涨的可能性,那就需要排查代码存在的问题。

小结

当然,CPU问题,远远不是我上文例子这么简单,我们也仅仅介绍了最初级的问题排查思路。也有许多的工具,适合不同场景下的问题排查思路,比如:

  1. vmstat,是一款指定采样周期和次数的功能性监测工具,我们可以看到,它不仅可以统计内存的使用情况,还可以观测到 CPU 的使用率、swap 的使用情况。但vmstat一般很少用来查看内存的使用情况,而是经常被用来观察进程的上下文切换。
  2. pidstat,之前的 top 和 vmstat 两个命令都是监测进程的内存、CPU 以及I/O使用情况,而pidstat命令则是深入到线程级别。

多种工具结合,逐步缩小问题范围,才是真正解决问题的处理方法,当然,更多的工具留给你自己去做尝试了。

内存调优

线上内存,常见的有下面三类问题

  1. 内存溢出
  2. 内存泄漏
  3. 垃圾回收导致的服务卡顿

新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 )

内存溢出

什么是内存溢出

当程序需要申请内存的时候,由于没有足够的内存,此时就会抛出OutOfMemoryError,这就是内存溢出。

下面我们来看一个例子

public class OomTests {
    static class OOMObject{
        public byte[] placeholder = new byte[640*1024];
    }

    static class OOMObject{
        public byte[] empty = new byte[64*1024];
    }

    public  static void add(int num) throws InterruptedException {
        List<OOMObject> list = new ArrayList<>();
        for (int i =0;i<num;i++){
            Thread.sleep(500);
            System.out.println(i);
            list.add(new OOMObject());
        }
        System.gc();
    }
    public static void main(String[] args) throws InterruptedException {
        add(1000);
    }
}

如下图可以看到,内存使用量持续飙升,超出最大堆容量后,出现OOM。

当然,可视化工具也可以直接看到出现OOM的堆栈情况。

当然,上面只是本地的一个测试demo,方便演示工具如何使用。线上OOM问题排查,我们有两种方式

  1. 使用jmap命令生成dump文件jmap -dump:live,format=b,file=heap.hprof <pid>
  2. JVM启动参数增加参数,当应用抛出OutOfMemoryError 时自动生成dump文件-XX:+HeapDumpOnOutOfMemoryError

通过Jprofiler,打开dump文件

选择最大对象,即可看到dump文件中最大的对象,也可以看到具体的引用情况。

内存泄漏

内存泄漏指程序运行过程中分配内存给临时变量,用完之后却没有被GC回收,始终占着内存,即不能使用也不能分配给其他程序,就叫做内存泄漏(也就是相当于占着内存却不能被管理到造成内存的浪费) 内存泄漏短期内或者说轻微的不会有太大的影响,但内存泄漏堆积起来后却会很严重,会一直占用掉可用的内存,从而出现内存溢出的现象。

常见问题

  1. 可以复用的对象,每次都new,但也不会回收,比如客户端连接
  2. 文件流操作,但是没有正常关闭

排查思路可以参照上面内存溢出的情况,排查大对象即可

G1垃圾回收器

关于垃圾回收,常见问题主要有两点

  1. 时间过长,垃圾回收存在STW,时间过长则会导致影响请求
  2. Full GC次数过多

我们的调优目标,自然也是围绕这两个来

  1. 响应速度
  2. 合适的吞吐量

G1(Garbage-First)是在JDK 7u4版本之后发布的垃圾收集器,并在jdk9中成为默认垃圾收集器。通过“-XX:+UseG1GC”启动参数即可指定使用G1 GC。从整体来说,G1也是利用多CPU来缩短stop the world时间,并且是高效的并发垃圾收集器。

排查垃圾回收问题,启动服务时一定要加上如下四个参数

-XX:+PrintGCTimeStamps :打印 GC 具体时间;
-XX:+PrintGCDetails :打印出 GC 详细日志;
-Xloggc:/log/heapTest.log GC日志路径
-XX:+UseG1GC 使用G1垃圾回收器

分析系统运行情况

  • 系统每秒请求数、每个请求创建多少对象,占用多少内存
  • Young GC触发频率、对象进入老年代的速率
  • 老年代占用内存、Full GC触发频率、Full GC触发的原因、长时间Full GC的原因

主要工具jstat,如下命令就是监控gc情况,每秒采样一次,采样10次

jstat -gc 44017 1000 10

为了方便大家看到区别,我手动出发了一次full gc,大家也可以明显看到,FGC从0变为了1。

S0C/S1C、S0U/S1U、EC/EU、OC/OU、MC/MU分别代表两个Survivor区、Eden区、老年代、元数据区的容量和使用量。YGC/YGT、FGC/FGCT、GCT则代表YoungGc、FullGc的耗时和次数以及总耗时。如果看到gc比较频繁,再针对gc方面做进一步分析。

磁盘&IO

笔者主要做的都是web服务,几乎不涉及到读写文件,最多也就是日志打印会设计到io,但是这块由于框架优化,几乎没有太多的性能损耗,个人也没排查过io相关的问题,在这里仅作一个命令的介绍。

如果你有线上IO问题排查经验,也欢迎评论区与大家交流

df -lh 查看磁盘使用情况

iostat 查看磁盘io

网络

查看TCP连接情况

常见问题 tcp队列溢出netstat -s |egrep "listen|LISTEN"

overflowed标识全连接队列溢出的次数,最前面是0,标识没有队列溢出的情况,网络环境正常。

网络是否连通

常见问题

  • rpc服务连接不上
  • 数据库、Redis中间件连接不上

使用telnet ip/域名 端口号 来查看网络是否连接

如果出现下图内容,则证明网络已经连接

全部评论

相关推荐

我是个没天赋的人,努力学习也只考上了个一本,家里条件也不怎么样。大一玩了一年,没怎么学技术,也没有卷绩点,全在游戏小说抖音中度过。大二上接触了牛客,看到了许多优秀的同龄人。很多双非的同学,甚至不少学院本的同学都进了大厂实习。我把他们作为榜样,决定好好学习。我每天都至少学八九个小时,很多次都想要放弃,想哭,我都坚持了下来。我总是告诉自己,只要努力,就一定能有好的结果。这几个月过的很累,但也很充实。转眼就到大二下了,我决定去找实习了,但是学校的认可度让我感到心底发凉,明明和广工这种知名双非分差不多,结果总被问是不是公办本科。两个月投了一千份实习,只有四个面试,最终去了个中小厂实习。结果就是改了两个月bug,虽然mt人挺好,但是实在学不了什么东西,所以就离职开始面试。凭借这段实习,确实多了不少中小厂面试,但是大厂依旧没有面试机会。除了字节腾讯所有大厂都投了,结果依旧是0面试。最终有幸获得美团的面试机会,面试也幸运的通过,然后入职了。为了省钱坐十几个小时硬座到北京,到北京的第一天,由于太激动想要租房,结果被坑了2600,之前实习的地方,房东也故意不退押金,加起来总共损失3000多。虽然很难过,但是我还是忍受了下来,我想着实习才刚开始,会好起来的。实习了大半个月,跟学校这边沟通一直不成功,我每天都寝食难安,精神都快崩溃了,经常凌晨两三点才睡着,想要跳楼。最后迫于无奈,我一大早我坐高铁回去,恳求院主任给我一个机会,我怎么恳求讲理都没用,甚至都磕头下跪了,还是没用。院主任一点机会都没给我,连让我跟各科老师沟通机会都不给,要不休学要不辞职。我没得选择,这段实习我看的比我的生命还重要,这不仅是我这大半年的心血,更是未来的一份希望。我只能休学,我想着现在好好实习,多学点技术,到时候秋招早点拿到offer,然后再补这学期的课也不是不行。但是,现实总是事与愿违。这三个月说实话并没有学到什么东西,前一个月很闲,这两个月事很多,每天基本都是九点后下班,但都是杂活。产出都是靠我看文档加上代码写上去的。我真的很想锻炼一下技术,但是总是不尽人意。三个月了,我到现在都还没做过一个像样点的需求。产出是能编,但有破绽不说还没锻炼到技术。我好想真正的做一下需求啊,我好想真正的走完一遍流程,去上线一次啊。接下来两个月,我不知道该怎么坚持下去了,现在每天都想哭,很焦虑,很难受。冒着将来可能延毕的风险,我赌上了一切,结果输的这么彻底,可能我就只是个小丑吧。如果家庭好点就不用卷了,如果我聪明一点就能上个好学校了,如果大一有人带我,我就不会摆烂了,如果院主任给我个机会,我就不用这么苦了,如果我实习能有机会好好锻炼自己,我就不用这么难受焦虑了。但是没办法,我又能怎么办呢,无非是咬紧牙关罢了,毕竟没人能够帮助我,只能靠自己我可真是个小丑啊
牛客57762807...:这种院长就是恶心的死,家里户口本只有一页的孤儿,我们院长也是,家里人都去亲自找院长,送几百块的水果,送礼物,结果还是被她一顿电话操作毁offer了,担心学生安全不放实习就算了,特么是担心上课没人去,我这种会容易带坏风气导致很多人效仿,***妈呢,什么时候学生的前途被一堆KPI数字给限制了,本来还想做个乖孩子的,以为院长能开开恩,但是这种死了没的东西让我决定我再也不做乖孩子了,后面才知道爱哭的孩子没有奶吃的,还会被一顿毒打,大三下学期我决定偷偷溜走一学期,一节课都不去,少的钱她一个孤儿也给我补不了
投递美团等公司10个岗位
点赞 评论 收藏
分享
huo12138:校友,传奇耐面王
点赞 评论 收藏
分享
评论
2
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务