当前位置: 首页 > news >正文

部署在linux上的java服务老是挂掉[排查日志]

最开始的时候,严重怀疑是内存不足导致的,但是一直没得排查,最近某个服务挂掉的几率越来越高了不得不排查一下。

先从jar自己打印的debug,error查起,发现在挂掉之前没有一点异常直接下一步(也没想着这里能查到什么)毕竟“启动成功、运行中突然挂,业务日志无异常”——99% 是进程被操作系统干掉或者 JVM 自己 Abort

直接上排查 "三部曲"

  • 确认“是谁”杀进程
  • 全局搜 JVM 崩溃日志
  • 看 GC 日志有没有“死循环”

1.确认“是谁”杀进程,看看是不是OOM Kill

什么是 OOM Kill ?

内核选择性杀掉某个进程来回收内存,这个过程叫 OOM Kill

直接输入下面的命令先查看

# 1. 系统日志里找 kill 记录
sudo journalctl --since "1 hour ago" | egrep -i "killed process.*java|oom-killer"

这个指令的意思是:

在系统日志(journal)里,搜索最近 1 小时内,涉及 Java 进程被杀掉或触发 OOM Killer 的记录。你可以通过修改journalctl --since "1 hour ago" 来实现查询更久之前的,我这里挂了就马上排查所有我只看1小时内的免得有其它影响

通过命令可以看到系统返回给我们的信息

答案已经呼之欲出了,警告信息:

Aug 13 14:21:32 VM-8-2-opencloudos kernel: sort invoked oom-killer: gfp_mask=0x140cca(GFP_HIGHUSER_MOVABLE|__GFP_COMP), order=0, oom_score_adj=0 Aug 13 14:21:32 VM-8-2-opencloudos kernel: Out of memory: Killed process 1461612 (java) total-vm:3390404kB, anon-rss:755084kB, file-rss:12044kB, shmem-rss:0kB, UID:0 pgtables:1964kB oom_score_adj:0

看到Out of memory:就表示系统内存不够了

Killed process 1461612 (java):内核杀掉了 PID=1461612 的 Java 进程

果然,oom kill了,系统主动杀了一个占用内存大的进程,也就是挂掉的那个服务

所以 Java 应用会莫名其妙挂掉,也不会生成 JVM hs_err_pid.log,因为这是 操作系统级别的强杀,JVM 根本没机会写日志.

还有另一种方式,直接查看内核缓冲区日志,跟上面那个方式差不多

# 2. 内核环形缓冲区
dmesg -T | egrep -i "killed process|oom_reaper|segfault

从该指令返回的信息我们可以看到这几个时间都发生了 OOM Kill 都因为内存不足导致的

使用命令查看我们内存使用情况

free -h

逐项分析:(但是着重看 used 和 available)

total 3.6Gi

物理内存总容量:大约 3.6 GB(可能是 4GB 物理内存减去一些保留给内核/显存的空间)。

used 3.5Gi

当前已使用的内存(包含应用、缓存等)。

free 120Mi

完全空闲、未分配的内存(非常少)。

shared 3.4Mi

共享内存占用(主要是 tmpfs、shm)。

buff/cache 157Mi

文件缓存、缓冲区(可被回收)。

available 81Mi

系统真正还能分配给应用程序的内存:只有 81MB,这个值低到随时会触发 OOM。

我们还可以通过下面的指令查看是谁吃的内存这么多,我这里是这几个java服务吃最多,吃完了

# 按内存占用排序

ps aux --sort=-%mem | head -20

-----------------------------------------------------------------------

这种情况加内存是最有效的方式

但是,我还想挣扎一下,我决定做这两步:

1.打开Swap, 开 2G 的swap

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

开机自启 swap

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

2.限制开销不大的服务最大堆的空间

把512m 改成 256m

第一步排查就已经查到问题了,三部曲都没走完,但是不是每一个人都是这种情况,下面两部也简单说一下

2.全局搜 JVM 崩溃日志

如果你不是 oom kill 导致的,那么jvm可能在"临kill"前会给你留下线索

# 最近 7 天内所有 hs_err 文件

sudo find / -type f -name "hs_err*.log" -mtime -7 2>/dev/null

  • 文件名匹配模式,找类似 hs_err_pid12345.log 这样的文件。

  • 这些一般是 Java 虚拟机(JVM)崩溃时生成的错误日志,里面会有堆栈、CPU、内存等信息。

然后分析这些日志排查一下

3.看 GC 日志有没有“死循环”

如果你没有打开GC日志,那你得在jar包启动指令上面加上下面这个指令,下次复现时就能拿到日志了

JAVA_OPTS="$JAVA_OPTS -Xloggc:$APP_HOME/logs/gc_%t.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps"

等下次复现之后就可以输入下面的指令查看了

grep -c "Full GC" logs/gc_*.log

http://www.dtcms.com/a/329836.html

相关文章:

  • Spring Boot调用优化版AI推理微服务 集成 NVIDIA NIM指南
  • 部署 Docker 应用详解(MySQL + Tomcat + Nginx + Redis)
  • mysql binlog常用命令
  • 2.从零开始写LINUX内核—导扇区与 Setup 程序开发
  • 充电宝频频自燃?PA300功率计来“把关”
  • robot framework
  • 选择gpt-5还是claude-4-sonnect
  • GPT-o3回归Plus用户,GPT5拆分三种模式,对标Grok
  • 深度学习·ExCEL
  • 在Ubuntu24.04中使用ssh连接本地git仓库到github远程仓库
  • [前端算法]排序算法
  • 用vscode开发和调试golang超简单教程
  • net/dial.go
  • QT之设计器组件功能(8大类55个组件)
  • 机器学习阶段性总结:对深度学习本质的回顾 20250813
  • Java 大视界 -- Java 大数据机器学习模型在金融资产配置优化与风险收益平衡中的应用(395)
  • golang语言和JAVA对比
  • Python 迭代协议与迭代器
  • 位图法(Bitmap)​​一维数据改为二维数据
  • OpenJDK 17 JIT编译器堆栈分析
  • 操作系统八股题
  • Mysql——如何做到Redolog崩溃后恢复的
  • “PDA采集→WMS智慧化分析→AGV执行”全链路管理的仓储系统
  • Qwen大模型加载与文本生成关键参数详解
  • I2c、SPI、USB驱动架构类比
  • Torch -- 卷积学习day1 -- 卷积层,池化层
  • 第四十四天:动态规划part11(第九章)
  • 存量竞争下的破局之道:品牌与IP的双引擎策略|创客匠人
  • scrapy 爬虫
  • sqli-libs通关教程(51-65)