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

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

死锁排查

首先给出死锁定义:

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

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

问题模拟代码

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

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

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

目录
相关文章
|
9月前
|
消息中间件 安全 算法
死锁和进程间通信
死锁和进程间通信
60 0
|
9月前
|
Linux
网络编程之信号(处理僵尸进程的终极办法)之初识信号捕捉器
接着我们之前的管道所提出来的问题() 在创建子进程之后,子进程究竟何时终止????调用waitpid函数后还要无休止的等待子进程终止吗???”,这显然会是一个问题。因为父进程往往与子进程一样繁忙,因此我们不能只调用waitpid函数来等待子进程终止。那么我们应该怎么办呢??? 信号闪亮登场!!!!!
75 0
|
4月前
|
Linux C++
Linux c/c++进程之僵尸进程和守护进程
这篇文章介绍了Linux系统中僵尸进程和守护进程的概念、产生原因、解决方法以及如何创建守护进程。
64 0
|
9月前
|
Linux C语言
Linux: 僵尸进程究竟是什么?有什么危害?
Linux: 僵尸进程究竟是什么?有什么危害?
176 0
|
7月前
|
消息中间件 算法 Java
(十四)深入并发之线程、进程、纤程、协程、管程与死锁、活锁、锁饥饿详解
本文深入探讨了并发编程的关键概念和技术挑战。首先介绍了进程、线程、纤程、协程、管程等概念,强调了这些概念是如何随多核时代的到来而演变的,以满足高性能计算的需求。随后,文章详细解释了死锁、活锁与锁饥饿等问题,通过生动的例子帮助理解这些现象,并提供了预防和解决这些问题的方法。最后,通过一个具体的死锁示例代码展示了如何在实践中遇到并发问题,并提供了几种常用的工具和技术来诊断和解决这些问题。本文旨在为并发编程的实践者提供一个全面的理解框架,帮助他们在开发过程中更好地处理并发问题。
123 0
|
7月前
|
NoSQL Linux Redis
c++开发redis module问题之避免在fork后子进程中发生死锁,如何解决
c++开发redis module问题之避免在fork后子进程中发生死锁,如何解决
|
9月前
|
安全 Java
多线程(CAS, ABA问题, Runnable & Callable & 僵尸线程 & 孤儿进程)
多线程(CAS, ABA问题, Runnable & Callable & 僵尸线程 & 孤儿进程)
82 1
|
9月前
|
Linux Shell 调度
【linux进程(四)】僵尸进程和孤儿进程概念&进程优先级讲解
【linux进程(四)】僵尸进程和孤儿进程概念&进程优先级讲解
|
9月前
|
Linux 调度
【Linux】详解进程状态之僵尸进程——孤儿进程
【Linux】详解进程状态之僵尸进程——孤儿进程
157 0
|
9月前
|
NoSQL Linux Shell
【进程概念】进程状态以及僵尸进程(结合代码)
【进程概念】进程状态以及僵尸进程(结合代码)

热门文章

最新文章

相关实验场景

更多