主要观点总结
蚂蚁埋点网关出现进程OOM导致闪退的问题,经过一系列分析和实验,最终定位到是由于单次请求携带大量埋点数据,内存池管理不精细,以及特定业务场景下内存释放不及时导致的。解决方案包括优化内存管理,提前释放内存,动态分配内存,使用更安全的编程语言等。
关键观点总结
关键观点1: 问题背景
蚂蚁埋点网关基于nginx开发,负责移动端埋点数据采集,出现偶发性进程crash,初步排除内存泄漏问题。
关键观点2: 初步分析
先排除了内存泄漏问题,初步怀疑内存使用不当或内存越界访问导致问题。
关键观点3: 核心难点
无法生成core-dump文件,无法直接定位问题原因。
关键观点4: 创新解决方案
在用户态实现一个oom-killer(青春版),通过主动杀死进程的方式产生core-dump文件。
关键观点5: 问题定位
通过core-dump文件定位到问题原因:单次请求携带大量埋点数据,由于重复字段多压缩率极高,绕过了请求body的尺寸限制;数据攒批发送阶段内存池分配粗旷,并且内存池释放速度远小于数据流入速度;高时效、多份写出的业务特性进一步加剧了内存消耗。
关键观点6: 解决方案实施
为schema埋点增加了单次请求最多携带的埋点条数限制;优化内存管理,提前释放内存,动态分配内存;使用更安全的编程语言等。
关键观点7: 小结
成功定位并解决网关上的问题,总结出在排查时要坚信现象背后必有原因,可以拿出来讨论、大胆假设、小心求证等心得。
文章预览
阿里妹导读 一个特殊请求引发服务器内存用量暴涨进而导致进程 OOM 的惨案。 问题背景 埋点网关是蚂蚁基于 nginx 开发的接入网关应用,作为应用接入层网关负责移动端埋点数据采集,从去年年底开始有偶现的进程 crash 问题。 好在 nginx 设计中 worker 进程闪退后 master 进程会重新拉起新的进程处理请求,埋点客户端也有重试机制,偶现闪退没有造成大的影响。 初步分析 说实话作为 C 语言应用,crash 也没什么好奇怪的 :),第一反应当然是业务代码有问题,查看机器内存的占用也没有大的起伏。 所以先排除了内存泄漏最终 OOM 导致进程闪退。 大概率是内存没用好,内存越界访问导致的。这种问题排查起来也挺简单,找部分机器开启 core-dump,拿到 core 文件一看就知道是哪里跪了。说干就干,线上找了部分机器开启开关,等问题复现后登录,就遇到了
………………………………