Java 进程“人间蒸发”:没有 hs_err、没有 OOM 异常,凶手是 Linux 的 OOM Killer
服务凌晨无声消失,没有 hs_err 文件也没有 OutOfMemoryError。dmesg 里一行 Out of memory: Killed process 揭开真相:JVM 堆加堆外内存把机器吃光,被内核枪毙。附排查命令、oom_score 原理和堆参数预留算法。
从一个关键词,发现新的思路。
服务凌晨无声消失,没有 hs_err 文件也没有 OutOfMemoryError。dmesg 里一行 Out of memory: Killed process 揭开真相:JVM 堆加堆外内存把机器吃光,被内核枪毙。附排查命令、oom_score 原理和堆参数预留算法。
监控里 load 飙到几十,top 里 CPU 却几乎空闲。原来 Linux 的 load 也统计 D 状态进程。用 vmstat、iostat -x、pidstat -d、iotop 和 ps 找出是磁盘慢还是 NFS 卡死,并讲清 await 与 %util 怎么读。
接口突然大面积报 Too many open files。先分清 ulimit、limits.conf、systemd LimitNOFILE 与容器的差异,再用 lsof、ss 统计连接状态,定位到 CLOSE_WAIT 堆积,根因是 HttpClient 响应没关闭导致连接泄漏。
磁盘告警 100%,du 加起来却只有一半。原来是日志被 rm 了,Java 进程还握着文件句柄。用 lsof +L1 找到它,/proc/PID/fd 截断止血,再顺带讲 inode 耗尽、大文件定位和 logrotate copytruncate。
备份脚本手敲一切正常,放进 crontab 却悄无声息地不执行。逐条排查 cron 服务与日志、PATH 环境变量、百分号转义、时区、权限、输出重定向、flock 防重叠、时间漂移,并对比 XXL-JOB。
一次上线连踩两个 Nginx 默认值:client_max_body_size 默认 1m 导致上传 413,Spring Boot multipart 与多层代理要逐层放开;WebSocket 每 60 秒断线,缺 Upgrade 头且 proxy_read_timeout 默认 60s。附 curl 复现命令与心跳方案。
前端喊“接口 502”,后端说“我这儿好好的”。本文讲清 502(上游连不上/被掐断)与 504(上游超时)的区别,用 error.log 原文加自定义 access_log 三个 upstream 变量定位问题,并解释 keepalive、重启瞬间 502 与 proxy_next_upstream 的坑。
某天早上全站弹“连接不是私密连接”,根因是 HTTPS 证书过期。用 openssl s_client 和 curl -v 看证书有效期与证书链,梳理 certbot/acme.sh 自动续期失败的常见原因,并给出提前 30 天告警的检查脚本。
从 ThreadPoolExecutor 的执行流程讲到生产环境线程池打满的完整排查链路:核心参数怎么算、JUC 常用组件怎么选、Executors 为什么不能用、CompletableFuture 默认线程池的坑,以及一次千万级短信发送任务把线程池压满的真实复盘。
一份能照着操作的 JVM 笔记:运行时数据区、对象创建与回收、G1/ZGC 怎么选、常用启动参数、jstat/jmap/jstack/arthas 的用法,以及一次大报表导出把堆撑爆的真实排查过程。