【线上问题排查】死锁和僵尸进程排查



死锁排查

首先给出死锁定义:

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象。

网上有很多讲死锁的文章,这里不做赘述,直接进入正题。

问题模拟代码

先写一段模拟代码,模拟死锁场景

我们创建两个锁和两个线程,让线程 1 先拥有锁 A,然后在 1s 后尝试获取锁 B,同时我们启动线程 2,让它先拥有锁 B,然后在 1s 之后尝试获取锁 A,这时就会出现相互等待对方释放锁的情况,从而造成死锁的问题,具体代码如下:

   /**
     * <p>
     * 死锁
     * </p>
     * @since 2022/3/27 12:58
     */
     
    @GetMapping("/deadLock")
    public void deadLock() {
        // 创建锁 A
        Object lockA = new Object();
        // 创建锁 B
        Object lockB = new Object();

        // 创建线程 1
        Thread t1 = new Thread(() -> {
            // 先获取锁 A
            synchronized (lockA) {
                System.out.println("线程 1:获取到锁 A!");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 尝试获取锁 B
                System.out.println("线程 1:等待获取 B...");
                synchronized (lockB) {
                    System.out.println("线程 1:获取到锁 B!");
                }
            }
        });
        t1.start(); // 运行线程

        // 创建线程 2
        Thread t2 = new Thread(() -> {
            // 先获取锁 B
            synchronized (lockB) {
                System.out.println("线程 2:获取到锁 B!");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 尝试获取锁 A
                System.out.println("线程 2:等待获取 A...");
                synchronized (lockA) {
                    System.out.println("线程 2:获取到锁 A!");
                }
            }
        });
        t2.start(); // 运行线程


    }

打包部署到服务器。并使用nohup java -jar &运行。

排查过程

这里介绍2种排查方式:Jconsole 和 Arthas

Jconsole

部署之后请求一下接口: http://localhost:8080/deadLock

在这里插入图片描述
点击线程标签页,点击检测死锁。
在这里插入图片描述
直接就把检测死锁的线程告诉我们了。非常方便。
在这里插入图片描述
在这里插入图片描述
然后我们看线程的执行路径,定位到了94行和113行的代码。,接下来的事就好办了。
在这里插入图片描述
我们回到程序中看代码就知道这2个线程互相等待导致了死锁。

Arthas

Arthas是阿里的一款定位问题的工具,功能强大,最近我特别喜欢用这个。
官方文档传送门

官方的在线文档教程特别好玩,像是在玩游戏一样。
在这里插入图片描述

再告诉大家一个小技巧,IDEA插件安装 Alibaba Cloud Toolkit,可以直接在IDEA上进行问题排查,不用登录服务器。

首先我们安装下插件
在这里插入图片描述

安装完之后我们得先配置一下主机,输入服务器的账号密码
在这里插入图片描述
配置完成之后点击 诊断
在这里插入图片描述
它就会自动帮我们下载Arthas到服务器上,直接在IDEA实现异常诊断。

IDEA在手,天下我有

在这里插入图片描述
直接输入 thread -b
如果不知道命令用法可以先输入:命令 -h 查看帮助信息,或者直接看官方文档。
在这里插入图片描述
直接就帮我们找到了持有锁的线程,并且还展示了阻塞了多少个线程!
🐂B
然后我们就知道了是当前这个线程持有锁导致其他线程被阻塞,找到对应代码解决就OK了。
Arthas还有很多非常强大的功能,大家自行探索,还是非常有趣的,可以帮助我们更好的排查问题。

僵尸进程排查

僵尸(zombie)进程定义

僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源。

一般僵尸进程很难直接kill,不过可以先kill僵尸的父进程。父进程死后,僵尸进程成为“孤儿进程”,过继给1号进程init,init始终会负责清理僵尸进程,它产生的所有僵尸进程也跟着消失。

排查过程

首先使用 top 命令可以知道是否有僵尸进程
在这里插入图片描述
使用 ps -A -ostat,ppid,pid,cmd |grep -e |grep -e '^[Zz]'命令定位僵尸进程
在这里插入图片描述
僵尸进程ID:25158
僵尸进程的父进程ID:22543

使用 kill -9 杀死僵尸进程的父进程
注:生产环境一定要检查确认僵尸进程的父进程退出是否对业务有影响

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农BookSea

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值