爬虫服务(chromedp)僵尸进程排查记录
2021/8/5 7:08:22
本文主要是介绍爬虫服务(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 的进程,有着特殊的使命:
- 传递信号,确保子进程完全退出
- 等待子进程退出
修复过程
本地测试时在docker run参数中加–init,经测试发现是ok的,但是服务是部署在k8s集群中,查了好久发现无法在deployment yaml文件中传递docker run的参数…
只能从镜像层面考虑解决。
首先打了一个有tini(docker-init实际使用的是tini)的镜像,然后修改Dockerfile:
最终上线完美解决!
僵尸进程已经消失不见。
参考:https://stackoverflow.com/questions/50803268/kubernetes-equivalent-of-docker-run-init
这篇关于爬虫服务(chromedp)僵尸进程排查记录的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27Rocket消息队列资料:新手入门指南
- 2024-11-27rocket消息队资料详解与入门指南
- 2024-11-27RocketMQ底层原理资料详解入门教程
- 2024-11-27RocketMQ项目开发资料:新手入门教程
- 2024-11-27RocketMQ项目开发资料详解
- 2024-11-27RocketMQ消息中间件资料入门教程
- 2024-11-27初学者指南:深入了解RocketMQ源码资料
- 2024-11-27Rocket消息队列学习入门指南
- 2024-11-26Rocket消息中间件教程:新手入门详解
- 2024-11-26RocketMQ项目开发教程:新手入门指南