导语

  • 服务器配置:2h4G8M
  • 最近服务器出现多个Java项目以及node项目一天被无故停止多次,保证没被入侵的情况下,且内存未占满,感觉挺常见的问题,故此记录一下解决思路

截图

项目停止图片

node项目停止截图

步骤

检查内存使用情况

​ 我这里使用ubuntu自带的htop命令进行查看,其它Linux可以top命令

htop

​ 发现内存还有一半,真离谱,排除内存问题。

检查登录记录

​ 由于系统日志文件被宝塔面板的日志模块接管了,再加上我手贱加了日志清理服务,直接文件被宝塔删除了,故此我只能检查宝塔自身的日志(不够权威)。

宝塔面板日志
宝塔内部日志文件

由此可见,没有可疑的操作记录以及登录记录,入侵的可能性也就排除了,其实也不能完全排除,但是谁让我把日志文件清了时没新建呢,没有系统日志的支撑,所以大家千万别学我图方便使用宝塔面板,埋下很多坑。内核日志没啥大问题,故此排除入侵可能。

检查系统内核日志

​ 由于PHP我使用了PHP-FPM守护进程,所以它可能也挂了,但是也恢复了,所以我想看看内核日志里有没有关于Java进程被系统给嘎了。

dmesg

​ 由图看来,几乎都是UFW对那些不对劲的源客户端IP进行拒绝的日志,再筛选一下。

dmesg | grep Java

​ 筛选后发现还是没有日志。排除内核。

思考

  • 其实到这,我就大概知道原因了,可能是大量程序多线程执行导致的某一时刻(我服务器上面随着时间的推移有了几个多线程程序),并发量大起来超过了我原来设置虚拟内存和实际内存,向操作系统申请物理内存时,操作系统会发现,物理内存已经没有了。此时,为了防止整个系统crash掉,linux内核会触发 OOM/Out of Memory killing 机制,即按照一定的规则选择一个进程,将其kill掉,以便回收物理内存,以此来保证机器整体的稳定运行。(关于虚拟内存的知识这边就不提了,感兴趣的可以自己查查
  • 这时候就可能是Java程序本身发生OOM导致的进程Crash(也就是代码有问题),以前就设置过Java每个项目最小最大内存使用,所以排除掉了。还有可能是JVM自身的故障原因,因为JVM最占用的便是虚拟内存,但是我更新了对JVM巨大优化的jdk11后还是有这个问题,且node项目也停了。
  • 所以总结起来,就是内存在某一时刻被挤爆了,JVM也申请不到虚拟内存,导致了low memory耗尽了,程序申请不到内存,系统触发OOM查杀了某些非Root用户、优先级不高的进程。

解决方案

  • 增加Linux其Swap分区大小,也就是增加虚拟内存,通过物理磁盘空间置换,虚拟内存可以让帮进程”扩充”内存,我原来的虚拟内存只设置了2G,一般设置成物理内存的1.5倍左右。Linux 中可以使用 SWAP 分区,在分配物理内存,但可用内存不足时,将暂时不用的内存数据先放到磁盘上,让有需要的进程先使用,等进程再需要使用这些数据时,再将这些数据加载到内存中,通过这种”交换”技术,Linux 可以让进程使用更多的内存。

  • 但是虚拟内存的 SWAP 特性并不总是有益,放任进程不停地将数据在内存与磁盘之间大量交换会极大地占用 CPU,降低系统运行效率,所以有时候我们并不希望使用 swap。有点拿CPU算力换内存那味儿了。

操作步骤

​ 参考百度大佬文章

Linux增加虚拟内存方法 - 默默的人生 - 博客园 (cnblogs.com)

通过观察了两天,发现问题得到了解决。