Linux 内存使用率缓慢增长排查,目前有一台服务器,上面部署了 17 个微服务应用,24G8C 的配置,所有应用启动后内存占用率在 45%左右,经过一个月的运行后内存会涨到 75%左右,然后服务器就 hung 住了,连 ssh 都无法连接,已经出现过两次了。
请问大佬们这种情况改从哪个方向再去排查一下。 目前即使向定位原因。
接下来会将应用拆分放到多台服务器上。
1
ricwangcom 2023-07-26 08:54:22 +08:00
微服务的日志把硬盘挤爆了?
|
2
diagnostics 2023-07-26 08:57:26 +08:00
ssh 连不上和内存没多大关系,SSH 后无法用 tab 补全那就是磁盘不足
|
3
wxd21020 OP @ricwangcom 磁盘没爆,内存爆了
|
4
wxd21020 OP @diagnostics 我感觉是没内存分配了所以 ssh 连不上了,因为重启机器后我查看了所有应用的日志,错误信息都是 OOM ,且没有内存创建 thread
|
5
Weixiao0725 2023-07-26 09:06:51 +08:00
按照进程监控内存?这种问题肯定先定位哪个程序引起的问题
|
6
mineralsalt 2023-07-26 09:07:06 +08:00
内存不可能凭空消失吧, 找到占用内存最多的进程, 排查它不就好了么
|
7
LindsayZhou 2023-07-26 09:09:06 +08:00
用 cgroup 限制一下各个服务的内存大小?
至少不影响服务器本身的运行。 |
8
wxd21020 OP @Weixiao0725 最近使用 top 隔几个小时我就会去看一遍,基本上有几个应用一天会长 0.1%,这是目前定位的最后手段了。
|
9
wxd21020 OP @mineralsalt 前五个应用占用内存差不太多,5.1,4.9,4.9,4.8,4.6
|
10
wxd21020 OP @LindsayZhou java 服务启动的时候倒是设置了 Xmx 。
|
11
Jackliu 2023-07-26 09:16:31 +08:00
内存泄漏
|
12
allenzhangSB 2023-07-26 09:24:36 +08:00
看下是不是堆外内存泄露了
|
13
llrasd 2023-07-26 09:25:55 +08:00
百度下 glibc 内存泄漏 ;之前我们有这个问题
|
14
wzy44944 2023-07-26 09:33:19 +08:00
服务器没有配置 OOM-kill 吗?可以先配一下,等有进程 oom 重启后,看下 dmesg 就知道是哪个了。可以用 cgroup 限制内存。不过你这个是多个微服务,也可以用一个 docker 跑所有微服务,容器启动参数加--memory 18G ,限制总内存在 18G ,这样 docker 内会 oomkill ,不影响你 ssh 到主机做排查。要复现就在 docker 启动参数再加个 --oom-kill-disable=true
|
15
Ggmusic 2023-07-26 09:34:41 +08:00 via iPhone 1
@wxd21020 划重点:没有内存创建线程。这种情况下系统的内存是足够的,但是你没法起新线程了,估计是有个 java 进程持续不断创建线程,可以监控下各个进程创建的线程数。https://www.bmc.com/blogs/outofmemory-java-threads/
|
16
crsmk01 2023-07-26 09:36:24 +08:00
贴下 os 版本、jvm 版本、相关的内存参数(堆、栈、Directory Memory 、Code Cache 等)
1 、是不是在用 docker / k8s 在运行这些微服务应用 ?如果是,贴下 docker 分配的内存 or 微服务 pod 的 request / limit mem 2 、如果只是一个主机直接跑 java 进程,可以观察一下出问题的时候 sys cpu 是否很高,挑占用内存较高的前三个进程,用 pmap -xp <jvm_pid> 看下结果 |
17
securityCoding 2023-07-26 09:50:53 +08:00 via Android
优先看系统日志找出有问题的进程
|
18
popvlovs 2023-07-26 09:51:43 +08:00
从现象上看,比较赞成#15 的推测,首先线程创建是要消耗内存的(只创建不释放也算一种泄漏,现象符合),另外创建的太多达到操作系统上限后,也会导致操作系统 hung 住无响应
|
19
quan7u 2023-07-26 10:03:13 +08:00
监控主机资源,看看文件描述符的增长趋势
|
20
hsymlg 2023-07-26 10:03:46 +08:00
看进程,jvm 监控的里面内存正常,并不代表 java 进程内存是正常的,我记得 java8 的大多数场景 jvm 一旦从 os 那边获取内存,就不愿意会还回去了。可以看看这个 https://stackoverflow.com/questions/30458195/does-gc-release-back-memory-to-os
|
21
leonshaw 2023-07-26 10:12:58 +08:00
Xmx 加起来有多少
|
22
Rv9H 2023-07-26 10:14:12 +08:00
cat /proc/meminfo 是啥?
echo m > /proc/sysrq-trigger dmesg 输出是啥 先分析操作系统这边是哪种类型的页面,看是用户态还是内核态的页面 如果是用户态 cat /proc/<pid>/smap_rollup 分析是哪个进程 |
23
leonshaw 2023-07-26 10:15:16 +08:00
OOM 日志是指 Java 的还是系统的?哪个进程的或者 kill 了哪个进程?
|
24
crsmk01 2023-07-26 10:24:56 +08:00
另外,这些微服务应用用的什么系统用户( root or 普通用户)在跑的 ?有没有监控过操作系统整理的文件描述符、总线程数?
/proc/sys/fs/file-nr /proc/sys/kernel/pid_max /proc/sys/kernel/threads-max (结合所有 /proc/<pid>/status | grep -i Threads 总和看下) |
25
hahastudio 2023-07-26 10:29:38 +08:00
不光要留意线程数,还要看看进程数
|
26
ElvisLiao 2023-07-26 10:41:45 +08:00
建议排查下堆外内存泄漏,如果不存在 gzip 之类的流没有关闭的话,我看你的症状大概率是 linux 的 ARENA 区导致的。
pmap -x <pid>|sort -gr -k2 |less ,看看是不是存在大量的 64M 的内存块。是的话,机器参数强制设置一下 export MALLOC_ARENA_MAX=1 |
28
wxd21020 OP @Ggmusic 线程数我也监控了,我目前是看 current 、deadlocked 、timed_waiting 、waiting 类型的线程,目前看没有出现大批量的线程。
|
33
wxd21020 OP @leonshaw java 服务的,报 OOM 的时候是 17 个服务大概在相同的时间段爆出来的,爆出来的时候 ssh 都连不上去了,没办法 kill 了
|
36
wxd21020 OP @tdy218 这个/proc/<pid>/status 下的 thread 我统计过,17 个服务每个都没超过 100.
|
37
opengps 2023-07-26 12:30:43 +08:00 1
linux 不熟,分享下 windows 平台的经验:对于操作系统,内存的概念可以展开几种分类,你现在排查疑似内存泄漏的目的,需要从“提交内存”下手,而不是只看“专享内存”,一看这俩内存的差额,二看启动时候和泄漏后的差额,对比出来时那个进程,然后再去 dump 分析具体泄漏的线程或者对象
|
38
OblivionStaff 2023-07-26 12:40:24 +08:00
磁盘 iops 正常吗
|
39
zhujinlong 2023-07-26 13:36:33 +08:00
先从操作系统层面检查哪些进程消耗了最多的内存
|
41
NoKey 2023-07-26 14:07:20 +08:00
系统自身没啥问题的情况下,持续监控应用的内存占比,如果应用持续上升,看哪个上升的最多,然后分析呗。占用内存有两种情况,一种是服务有问题,就是内存泄露了,要找出来解决掉;一种是,他就是在一定时间后,要占这么多,占到一定峰值后,不会继续增加,那么这就是看服务自身是不是就需要比较大内存,单独给一台服务器。
|
42
flexbug 2023-07-26 14:08:09 +08:00
不如装个 process exporter 监控下每个应用占用
|
43
AlohaV2 2023-07-26 14:35:49 +08:00
是不是内存碎片太多了? buddyinfo 看一下
|
44
anticipated 2023-07-26 14:53:23 +08:00
先加点虚拟内存,防止死机,然后写脚本,记录一下,每几分钟输出各个资源的使用日志,大概几个小时就能找到问题了。
|
45
tin3w5 2023-07-26 15:04:30 +08:00
听起来像是内存泄漏,从经验上来看,大概率是 JVM 的锅。早些年在公有云厂商,大部分的 OOM case 都是开发的 Java 代码写的太烂导致 JVM 内存泄漏。
想起了之前在公有云厂商的时候,几百个 VIP 客户,用 Java 开发业务的能占一大半。同样是用 Java 开发的,那么几家公司就是经常 OOM 。你帮他诊断出来就是 JVM OOM 了,个别那一两家就非要跟你扯“我这代码在自己的笔记本上就不 OOM ,在你家公有云上就 OOM ,所以就是你家公有云的问题”。还要拉着你一起看 Java 代码……MMP 老子要是 Java 开发那么精通,老子第一个去你们公司把你给替了。 所以之前我们经常吐槽,Java 程序员的优劣,写小项目看不出来,写大项目就能看出来了。 |
46
wxd21020 OP @me1onsoda 分析了,dump 和 gc 都分析了,没发现问题,现在包 OOM 是因为服务器没内存供使用了,而不是 java 服务导致的 OOM
|
47
wushenlun 2023-07-26 16:01:37 +08:00 via Android
是不是 ubuntu20.04 和 22.都有这种 Bug ,,应该是跟平台+系统有关系,我现在跑 fedora 了
|
50
bli22ard 2023-07-26 16:51:34 +08:00
每个应用配置 -Xmx ,所有应用-Xmx 相加 < 系统启动内存 - 4G 。 这样让出现 oom , 是 jvm 自己,而不是 os oom 。这样就能找到有问题的那个系统, 然后再这个系统 oom 的时候, 使用 jmap dump 内存,进行分析,看看是哪里发生了问题, 是内存变量, 还是网络连接(包括中间件网络连接)。
|
52
yesh0 2023-07-26 17:04:54 +08:00
可能可以先配置一个 earlyoom 或者类似的来在临近 oom 的时候把进程杀掉避免 ssh 都上不去的情况?( Linux 内核的 oom killer 不太行,会在真正开杀之前丢掉硬盘缓存卡好长一段时间。)然后就是看 earlyoom 日志看看哪个进程被杀掉了针对性看一下吧。
earlyoom: https://github.com/rfjakob/earlyoom |
53
ffw5b7 2023-07-26 17:26:14 +08:00 via Android
Dump 的文件是不是很小?程序使用了 NIO 吗,是的话看下直接内存
|
54
vivisidea 2023-07-26 17:49:33 +08:00
可能是 kernel pagecache ,我们之前有过类似的问题,跟 jvm 啥的没关系
echo 3 > /proc/sys/vm/drop_caches 试试在内存比较高的时候执行这个命令(需要 root 权限) |
55
cheng6563 2023-07-26 17:54:37 +08:00
ssh 连不上,用云控制台后台的远程连接可以直接连到虚拟机的屏幕上,这时说不定就能连了。
|
56
atlantic2477 2023-07-26 17:57:10 +08:00
1 、确认应用是否有内存泄漏
|
57
atlantic2477 2023-07-26 18:01:29 +08:00
1 、确认应用是否有内存泄漏
2 、应用没有内存泄漏的话排查下内核 slab 各对象内存占用情况 之前遇到过类似的情况,应用没有内存泄漏,但是容器内存缓慢增加。最后发现是有一个应用每次处理请求都会在临时文件下创建文件然后删除,随着请求量增加导致 slab 中 dentry 对象占用过多内存增加 |
60
wxd21020 OP |
61
vivisidea 2023-07-26 20:38:13 +08:00
|
62
crsmk01 2023-08-03 10:21:49 +08:00
1 、上面说分析 dump 文件的同学都没审题,LZ 说了是 java.lang.OutOfMemoryError: Unable to create new native thread ,而且 LZ 像是做主机运维的 ?不要只盯着服务器内存,可能有误导性;
2 、可以看下 https://www.cnblogs.com/rexcheny/p/9502248.html 这篇文章; 3 、昨晚一个客户遇到了一个几乎一样的问题,还没完全排查完,但看第 2 点的文章就比较有用。 |