1.生产上的服务器,运行到2天左右就会产生core文件,在家折腾了两天,把一些过程记录下来,
希望能帮上有需要的人。
gdb /usr/lib64/erlang/xxx/xxx/beam.smp core.3435
....
gdb) bt
#0 0x0000003b5bc30265 in raise () from /lib64/libc.so.6
#1 0x0000003b5bc31d10 in abort () from /lib64/libc.so.6
#2 0x000000000044f3b0 in erl_exit ()
#3 0x00000000004380a4 in erts_alc_fatal_error ()
#4 0x0000000000438131 in erts_alloc_n_enomem ()
#5 0x000000000051e918 in ?? ()
#6 0x000000000052090f in ?? ()
#7 0x000000000051d8fc in erts_garbage_collect ()
#8 0x00000000004bc3c0 in schedule ()
看到erlang运行时分配内存不足
2. 代码有死循环? or 非法的用户用脚本在刷服务
那就远程看一下在线的服务器运行情况
3. 看日志和内存分配情况
3.1 远程调用
ctrl + G
r ‘[email protected]‘
(或是 erl -name ‘[email protected]‘ -setcookie xxxx -remsh ‘[email protected])
3.2 查看内存使用情况
erlang:memory(processes).
3788 928 024
erlang:memory(ets).
970 627 328
erlang:memory(total).
4 863 713 656
erlang 系统运行时,内存占了近5个G,用不了24小时,系统肯定会再崩溃,
从上面可以看到ets表占用比较高,进程占用更高,
猜想下,有没有可能,是ets表导致的owner进程 占用了过4G的内存?
3.3 查看ets表的信息
ets:i().
sessions sessions set 232182 116713476 xxxx_service (116713476 words = * 8 = 933 707 808 bytes ~= 1G )
sys_dist sys_dist set 3 455 net_kernel
发现sessions表有在线用户23W,这个在线用户量,到是在正常范围,但会话会轮询,定期清除闲置的进程用户,
不应该一直保持在23w,一定是那里没有来得急释放。
xxx_service 的代码里找到释放缓存的代码,在本地插入一些用户,测试下,结果释放sessions没有问题。
怎么回事,可以释放,结果没有释放,代码应该没有问题。
往往这时,请再坚持一下,代码可能有问题,接着找吧。
3.4 既然进程占内存那么高,那就看看是那些进程,运行 etop
spawn(fun() -> etop:start([{output, text}, {interval, 3}, {lines, 20}, {sort, memory}]) end).
Pid Name or Initial Func Time Reds Memory MsgQ Current Function
----------------------------------------------------------------------------------------
<14099.124.0> xxxxxxxxxxx_service ‘-‘**************** 0 gen_server:loop/6
<14099.41.0> xxxx_server ‘-‘ 618605525150288 0 gen_server:loop/6
排第一的,内存多少都变*** 号了,这是非常高了才这样的。估计1G应该是有的,而且还一直在执行loop,说明
是什么东西处理不过来。
3.5 查看占用内存最多的进程的信息
Pid = whereis(xxxxxxxxxxx_service).
process_info(Pid) .
{
{total_heap_size,456131400},
{heap_size,228065700},
{stack_size,9}
456131400 * 8 = 3.6G 内存 (words * 8 ,64位系统)
基本可以肯定问题出在了这个进程。
这个进程很有可能是在操作ETS时,出的问题,应该找该模块与ets相关的代码。
3.6 找是找到了,ets相关的操作,但测试还是可以清除,也没有生产的问题。
猜想,是不是测试时用户的量没有达到。
再看看那段代码,有一个select的操作,是查找某段时间内,所有sessions,
然后对sessions进行持久化操作,然后清除,
当23W 用户同时进行持久,这个进程会不会阻塞?
3.7 分批次进次持久和清除操作,花了半天的时间,开发好,测试没问题了,
但感觉还有点不爽快,因为效率不高啊。
3.8 持久的清除解藕。
4. 上线12小时后,再查看线上服务的结果
11768 103 7.6 1110136 612668
物理内存只存7.6,
再看sessions 只有2W左右
这样,码农的心情变好了点........
5.谢谢。
版权声明:本文为博主原创文章,未经博主允许不得转载。