#!/usr/bin/env bash
# ==============================================================================
# 脚本名称: check_java_deadlock.sh
# 功能描述: 自动化 Java 死锁探测与线程池状态全景分析 (纯只读)
# 使用方式: 在运行 Java 的宿主机/容器内以 root 权限执行
# ==============================================================================
set -o pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PLAIN='\033[0m'
echo -e "${BLUE}================================================================${PLAIN}"
echo -e "${BLUE} Java 线程阻塞与死锁自动化探测 ${PLAIN}"
echo -e "${BLUE}================================================================${PLAIN}"
# 1. 获取 Java 进程号
if command -v jps &>/dev/null; then
JAVA_PID=$(jps -l | grep -v "sun.tools.jps" | head -n 1 | awk '{print $1}')
else
JAVA_PID=$(ps -ef | grep -i java | grep -v grep | head -n 1 | awk '{print $2}')
fi
if [ -z "$JAVA_PID" ]; then
echo -e "${RED}[ERROR] 未探测到正在运行的 Java 进程。${PLAIN}"
exit 1
fi
echo -e "${GREEN}[INFO] 锁定目标 Java 进程 PID: ${JAVA_PID}${PLAIN}"
# 2. 检查 jstack 工具
if ! command -v jstack &>/dev/null; then
echo -e "${RED}[ERROR] 当前环境缺少 jstack 工具,无法执行堆栈提取!${PLAIN}"
exit 1
fi
# 3. 抓取堆栈快照
DUMP_FILE="/tmp/jstack_deadlock_check_${JAVA_PID}.log"
echo -e "\n${YELLOW}[1/3] 正在导出线程快照至 ${DUMP_FILE}...${PLAIN}"
jstack "$JAVA_PID" > "$DUMP_FILE"
# 4. 自动匹配是否存在死锁
echo -e "\n${YELLOW}[2/3] 正在分析 JVM 死锁报告...${PLAIN}"
DEADLOCK_LINE=$(grep -n "Found one Java-level deadlock" "$DUMP_FILE" | cut -d: -f1)
if [ -n "$DEADLOCK_LINE" ]; then
echo -e "${RED}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!${PLAIN}"
echo -e "${RED}[ALERT] 实锤命中 Java 死锁!详细报告如下:${PLAIN}"
echo -e "${RED}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!${PLAIN}"
tail -n +"$DEADLOCK_LINE" "$DUMP_FILE"
else
echo -e "${GREEN}[OK] 未发现 JVM 原生 Java-level deadlock 死锁。${PLAIN}"
fi
# 5. 统计线程状态分布
echo -e "\n${YELLOW}[3/3] 统计当前线程池状态分布...${PLAIN}"
echo -e "${BLUE} 数量 状态名${PLAIN}"
grep "java.lang.Thread.State:" "$DUMP_FILE" | awk '{print $2}' | sort | uniq -c | sort -nr
echo -e "\n${BLUE}================================================================${PLAIN}"
echo -e "${BLUE}巡检完毕。若无死锁但 WAITING 偏高,请重点排查数据库连接池与下游依赖。${PLAIN}"
echo -e "${BLUE}================================================================${PLAIN}"