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

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

死锁排查

首先给出死锁定义:

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

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

问题模拟代码

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

我们创建两个锁和两个线程,让线程 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 杀死僵尸进程的父进程

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

目录
相关文章
|
1月前
|
消息中间件 安全 算法
死锁和进程间通信
死锁和进程间通信
25 0
|
8月前
|
消息中间件 缓存 算法
死锁和进程通信
死锁和进程通信
56 0
|
安全 算法 调度
411操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(四)
411操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁
134 1
411操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(四)
|
算法 调度 C++
410操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(三)
410操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁
180 1
410操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(三)
|
算法 调度
409操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(二)
409操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁
225 1
409操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(二)
|
存储 消息中间件 程序员
408操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(一)
408操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁
340 1
408操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(一)
|
消息中间件 算法 安全
【操作系统】第十一章死锁与进程通信
【操作系统】第十一章死锁与进程通信
138 0
【操作系统】第十一章死锁与进程通信
|
消息中间件 存储 前端开发
前端备战21秋招之操作系统,线程/进程/死锁
前端备战21秋招之操作系统,线程/进程/死锁

相关实验场景

更多