家里的all in one上有个服务总是每过几天就被杀了进程, 忍了很久之后实在忍不了, 进行了一番调查.
第一步, 查找oom记录
sudo grep -E -i -r "killed process" /var/log 查找到有这样几个文件: grep: /var/log/journal/baaa/system@eeeeeesdf.journal: 匹配到二进制文件 grep: /var/log/journal/baaa/user-1000.journal: 匹配到二进制文件 grep: /var/log/journal/baaa/user-1000@ee9sdf.journal: 匹配到二进制文件 直接看system文件 journalctl --file=/var/log/journal/baaa/system@eeeeeesdf.journal
第二步, 定位oom报错日志
12月 27 15:24:03 Server kernel: oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/user.slice/user-1000.slice/session-2.scope,task=Web Content,pid=2123123,uid=1000 12月 27 15:24:03 Server kernel: Out of memory: Killed process 2123123(Web Content) total-vm:16110516kB, anon-rss:6583136kB, file-rss:232kB, shmem-rss:1932kB, UID:1000 pgtables:27660kB oom_score_adj:0 2123123进程就是被杀掉的业务进程. 日志往上翻一翻,可以看到内存不足了, free -mh看一下, 可用内存果然极少了.
第三步, 定位真凶
ps aux --sort=-%mem | awk '{print $6/1024 " MB\t\t" $11}' | head -n 10 名为puma的多个进程占用了N个G内存, 查了一下, 是gitlab的服务.
第四步, 解决问题
尝试对gitlab进行优化配置(默认的gitlab设置是应对高性能大流量的, 我自用的git完全不需要这么高性能)
--env GITLAB_OMNIBUS_CONFIG="puma['worker_processes'] = 0; sidekiq['concurrency'] = 10; prometheus_monitoring['enable'] = false; gitlab_rails['env'] = { 'MALLOC_ARENA_MAX' => 2 };"
重启gitlab docker镜像, 再次查看内存占用, 剩余10G内存, 问题解决
容器占用的内存仍然出现了无限制增长的情况, 因此加上容器资源限制以阻止此类事情的发生.
--memory=4g \
--memory-swap=8g \
第二天(2023-12-29)发现, 业务程序(一个跑着selenium firefox的python程序)的web content标签页仍然会因为oom被杀掉, 奇怪的是此时仍有充足的物理内存, 但是在oom的那会儿, 大概有5~10分钟连ssh都因为oom无法连接.
因此特地安装了netdata程序对机器进行全面监控, 初步怀疑是firefox在长期打开那个业务页面时出现了内存泄漏, 但奇怪的是, firefox物理内存并没有持续增长, 只是虚拟内存有少量的持续增长, 还有待更长时间的观察.
观察了几个小时后之后发现, 原本内存占用平稳的webbrowser进程会突发内存占用, 可能是内存泄漏, 物理内存和虚拟内存同时大量占用, 疯狂申请内存直到整台机器的内存耗光.
采用的解决方法是业务程序使用轮询备用机制滚动替换webdriver, 相当于定时重启了selenium, 被关闭掉的webdriver会释放内存, 因此理论上可以解决这个问题.
怀疑是firefox导致的内存泄漏, 更换为chrome后, 虽然内存占用少了一半(~250M), 但是过几天之后仍然会出现内存占用狂涨导致OOM的情况.
最后只能采用轮询滚动替换机制周期调小来解决, 原本1个小时一次调整为5分钟一次.