爬虫服务(chromedp)僵尸进程排查记录

目录

发现现象

如何解决?

临时解决

根本上解决

修复过程


发现现象

我们的爬虫服务会使用chromedp库(https://github.com/chromedp/chromedp)模拟浏览器登录,抓取网页数据,某天在pod内查看服务运行状态时,发现有大量的zombie进程,看了下是Chrome进程,在这里记录下排查以及解决的过程,希望可以给其他遇到相同问题的人提供一些思路。

爬虫服务使用Chrome,应该是以创建子进程的方式来启动Chrome,如果在子进程销毁时没有wait或者waitpid来处理,那么子进程会成为zombie进程。

每个zombie进程会占用系统少量资源,造成资源泄露,最明显的是pid数量会逐渐变多,最终结果会造成无法启动新的进程。

如何解决?

临时解决

发现问题首先想的是快速恢复,而不是去定位解决问题。一开始准备将所有的僵尸进程kill掉,但是发现僵尸进程很难被kill掉,kill -9也不行。

后考虑kill掉其父进程,然后所有的僵尸进程就可以挂到init进程上,init会清理僵尸进程,然后看了下发现容器内没有init进程,所有僵尸进程的父进程都是1,进程1对应的是爬虫服务,杀掉1进程会导致容器挂掉重启……

后面直接重启服务临时解决了。

根本上解决

考虑到僵尸进程的产生原因,首先想到的是对于chromedp库的使用有问题,可能没有正确的关闭浏览器,去看了下代码内的使用,以及官方示例的代码,发现没有问题,所有的资源都被关闭了……

然后去chromedp库的issue中查找相关的内容,可能会有人遇到相同的问题。

发现一个类似的open状态的issue:https://github.com/chromedp/chromedp/issues/752

总结了几个观点:

  • 关闭浏览器时,kill掉chrome进程,但是这样太暴力,可能会影响其他使用chrome的线程。
  • 一些Chrome在被启动的时候,会有一个wrapper,例如shell,shell会启动Chrome作为子进程,执行完后,shell退出了,Chrome成为孤儿进程,挂到pid1进程上,但是容器内pid为1的进程为业务进程,没有回收僵尸进程的能力。

看了下chrome运行时的状况,发现开始的父进程并不是1,但到最后都变成了1,并且变为defunct状态。

在上面的issue中,有人提供了一个pr,并且被merge了,所以考虑升级库版本来解决,但是发现升级没有解决……

考虑其他方案。

后来发现一种方案,在docker运行时加入--init参数,这样docker内1号进程就是docker-init进程,业务进程则是其子进程。

docker-init进程会将收到的信号传递给其子进程,并且会处理僵尸进程。

然后自己在本地实验了下,同样的使用chromedp库,发现拥有docker-init进程的容器内,没有产生僵尸进程,因为1号进程已经具备处理僵尸进程的能力。

而1号进程是业务进程的容器内,僵尸进程逐渐积累……

同时实验了下信号捕获,看业务进程能否捕获退出信号,实验也是ok的。

ps:

通过本地实验,发现bash作为1号进程、业务进程作为其父进程的情况下,也可以处理僵尸进程,但是却不能传递退出信号给业务进程。

所以对于Linux 来说,pid 为 1 的进程,有着特殊的使命:

  1. 传递退出信号,确保子进程正确退出
  2. wait子进程退出,回收僵尸进程

修复过程

本地测试时在docker run参数中加–init,经测试发现是ok的,但是服务是部署在k8s集群中,查了好久发现无法在deployment yaml文件中传递docker run的参数…

只能从镜像层面考虑解决。

首先打了一个有tini(docker-init实际使用的是tini)的镜像,然后修改Dockerfile:

tini库地址:https://github.com/krallin/tini

最终上线完美解决!

僵尸进程已经消失不见。

参考:https://stackoverflow.com/questions/50803268/kubernetes-equivalent-of-docker-run-init

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值