软件环境
1G 1U 阿里云ECS 服务器, 集中部署 buukle-cms , buukle-gateway , buukle-www 三个项目.
现象
项目发布完, 正常访问一段时间后,buukle-gateway,buukle-cms随机出现宕机现象.
排查步骤
1. jvm监控
1.1 查看进程
ssh登录服务器,使用如下命令查看在运行的java进程:
jps -m -l
结果 :
前边是进程号,后边是应用名称 .
1.2 查看jvm堆内存情况
使用如下命令, 查看指定应用的堆内存分配情况 :
jmap -heap 进程号
结果 :
我们可以看到:
新生代(New Generation)占用了30.9375MB的内存,其中包括 Eden区和survivor区;新生代剩余 19.21MB;
永久代(tenured generation) 占用了68.56640625MB 内存,剩余 16.626MB;
内存使用正常,且比例符合G1收集器默认的内存分配比例,静态观察JVM没有发现问题;
然后通过java VisualVM 动态监控了一段时间同样也没有发现问题.
(java VisualVM 使用方法 : java VisualVM 远程监控(springboot-jar))
查看程序日志,也没有OOM异常,所以排除了JVM的问题.
1.3 怀疑是堆外内存作祟
查看系统日志,发现是系统内存不足, 操作系统将java进程杀掉了 .
我们好奇,一个java应用究竟占多少内存?
使用如下命令查看buukle-www应用所占内存:
top -p 进程号
结果 :
一个springboot 服务大概占300M左右. 我们在之前看到, 其堆内存总共有 30.9375MB + 68.56640625MB = 100MB;
可知,堆外内存占用了 200MB左右的空间.
使用 free -h 查看系统内存信息 :
我们发现,系统本身剩余991MB的内存, 而我同时部署了 buukle-www,buukle-cms,buukle-gateway 三个应用,没个应用大概占300MB左右内存. 当有访问进来时,系统堆外内存使用上升. 当并发请求过多,或者后台任务占用堆外内存过多, 超出了系统内存的容量, linux就会对当前最占用资源的进程进行kill,以保证系统的运行.
1.4 解决
暂时是在每次发布后手动 kill cms应用,cms需要在另外的服务器上部署.
其实也可以尝试通过设置linux swap分区,利用硬盘内存缓和一下内存需要, 但是会导致应用请求变慢,暂时未采用.
评论区