背??景前两篇讲了云主机上luaopenresty项目的容器化过程。在测试环境经过一段时间的验证,一切顺利,灰度开始上线。然而,好景不长。没过多久,灰阶就出现了。当我用toppod查看的时候,发现内存满了。一开始怀疑是k8s的resourcelimitmemory(2024Mi)的分配太小了。放大后(4096Mi),重启pod,很快又满了。紧接着,我怀疑是负载过大,负载过高造成的。我扩展了HPA并重新启动了它。好家伙,不到两炷香又满了。此时,我将注意力转向了pod内部的程序,估计是哪里发生了内存泄漏。坑在哪里?每一次,内存都在涨涨跌跌,nginxworker(子进程)的id号不断增加。谁杀死了进程?云主机没有这个问题,是k8s导致的吗?增加pod的资源限制内存和增加HPA都不能解决问题。nginx-sreload可以释放内存,但是过一会又满了。解决方案谁杀死了进程?命令:psauxUSERPID%CPU%MEMVSZRSSTTYSTATSTARTTIMECOMMANDroot10.00.02526725844?SsJun110:00nginx:masterprocess/data/openresty/bin/openresty-gdaemonoff;nobody86510.10.389032?S14:567:14nginx:workerprocessnobody86613.00.3860164586748?S15:137:02nginx:workerprocessnobody93115.60.2759944486408?R15:315:37nginx:workerprocessnobody93813.30.1507784234384?R15:492:23nginx:workerprocess发现woker进程号接近1000,必须连续杀掉,然后重启,那么是谁干的呢?通过dmesg命令:[36812300.604948]dljgoinvokedoom-killer:gfp_mask=0xd0,order=0,oom_score_adj=999[36812300.648057]Taskin/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pode4ad18fa_3b8f_4600_a557_a2bc853e80d9.slice/docker-c888fefbafc14b39e42db5ad204b2e5fa7cbfdf20cbd621ecf15fdebcb692a61.scopekilledasaresultoflimitof/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pode4ad18fa_3b8f_4600_a557_a2bc853e80d9.slice/docker-c888fefbafc14b39e42db5ad204b2e5fa7cbfdf20cbd621ecf15fdebcb692a61.scope[36812300.655582]memory:usage500000kB,limit500000kB,failcnt132[36812300.657244]memory+swap:usage500000kB,limit500000kB,failcnt0[36812300.658931]kmem:usage0kB,limit9007199254740988kB,failcnt0……[36675871.040485]Memorycgroupoutofmemory:Killprocess16492(openresty)当linux发现cguporldsacrificegroupkernel不足时触发insufficient选择杀掉一些进程,这样可以回收一些内存,尽量让系统保持运行状态。虽然kill掉nginxworker进程后释放了内存,暂时解决了问题,但是并没有解决根本问题。为什么云主机没有问题?将云主机的lua代码复制到本地进行对比,发现代码本身并没有什么问题。那只能是由其他问题引起的。我应该怎么办?以上两点都不能很好定位问题。看来只能通过top、pmap、gdb等命令来排查问题了。1、使用top查看是哪个进程占用了高端内存。PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND942nobody200618.9m351.7m4.2mS18.00.24:05.72openresty943nobody200413.8m146.7m4.2mS11.70.11:18.940nobodyopenresty200792.0m524.9m4.2mS7.00.36:25.81openresty938nobody200847.4m580.2m4.2mS3.70.37:15.97openresty1root200246.8m5.7m3.9mS0.00.00:00.24openresty2.pmap查看进程的内存分配,使用pmap-xpid查找Processmemoryallocation,发现在0000000000af7000处有一个很大的内存分配AddressKbytesRSSDirtyModeMapping000000000040000015729120r-x--nginx0000000000788000444r----nginx0000000000789000148128116rw---nginx00000000007ae0001402828rw---[anon]0000000000a15000904900900rw---[anon]0000000000af7000531080530980530980rw---[anon]0000000040048000128124124rw---[anon]......3./proc/pid/smaps获取内存地址后定位内存泄漏的地址范围大内存,使用cat/proc/pid/smaps命令查看内存段的具体起始位置:00af7000-21412000rw-p0000000000:000[heap]Size:533612kBRss:533596kBPss:533596kBShared_Clean:0kBShared_Dirty:0kBPrivate0_BPrivate:533596kBReferenced:533596kBAnonymous:533596kBAnonHugePages:0kBSwap:0kBKernelPageSize:4kBMMUPageSize:4kBLocked:0kBVmFlags:rdwrmrmwmeacsd4。gcore转储进程映像和内存上下文gcorepid以获取“core.pid”文件5.gdb加载内存信息gdbcore.pidsh-4.2$gdbcore.942GNUgdb(GDB)RedHatEnterpriseLinux7.*Copyright(C)2013FreeSoftwareFoundation,Inc.LicenseGPLv3+:GNUGPLversion3orlater
