解决 Docker + selenium + chromedriver + chrome 会出现僵尸进程的问题

news2024/12/25 10:24:42

一、僵尸进程问题

在docker里,使用selenium爬虫,  webdriver quit后,会产生很多僵尸进程。
docker run  - it  - v / home / blackip :/ home / blackips /   selenium : 1.0   python3 linux_black_ip . py
top查看僵尸进程:
ps -ef | grep defunct查看僵尸进程:
僵尸进程的父进程是python3。
看了下chrome运行时的状况,发现开始的父进程并不是1,但到最后都变成了1,并且变为defunct状态:
ps -ef | grep chrome| grep -v defunct
超多的僵尸进程会耗尽 pid 表,导致 Chrome failed to start: exited abnormally.
snapshot-consumer | selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally.
snapshot-consumer | (unknown error: DevToolsActivePort file doesn't exist)
snapshot-consumer | (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
snapshot-consumer | Stacktrace:

二、原因分析

在调查了进程树之后,终于发现:chromedriver fork出了多个子进程和一个孙进程,而 调用quit后,chrome driver正常退出,而它的子孙们变成了孤儿进程 ,被托管给了docker的1号进程,也就是docker的启动进程。这些孤儿进程退出后,根据孤儿进程托管的优先级,最终由1号进程托管,而 1号进程是业务进程, 没有能力处理子进程退出的信号 (wait/waitpid),这些孤儿进程就变成了僵尸进程
   
对于Linux 来说, pid 为 1 的进程,有着特殊的使命
  1. 传递退出信号,确保子进程正确退出
  2. wait子进程退出,回收僵尸进程

三、解决办法

3.1、脚本内部加入信号处理的方法

参照文章: docker,孤儿进程和僵尸进程 - 简书
在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN,这样,内核在子进程结束时不会产生僵尸进程。python 可以调用singal包来处理。
 
signal包的核心是使用signal.signal()函数来预设(register)信号处理函数:
参照:
  1. Python模块之信号(signal) - 每天进步一点点!!! - 博客园 (cnblogs.com)
  2. (7条消息) Python Signal(信号) 异步系统事件_jhonguy的博客-CSDN博客
singnal.signal(signalnum, handler)
参数:
  • signalnum为某个信号,
  • handler为该信号的处理函数。
我们在信号基础里提到,进程可以无视信号,可以采取默认操作,还可以自定义操作。当handler为signal.SIG_IGN时,信号被无视(ignore)。当handler为singal.SIG_DFL,进程采取默认操作(default)。当handler为一个函数名时,进程采取函数中定义的操作
​
# python3
# 开头加入如下代码,告诉此进程 SIGCLD的信号用SIG_IGN方法处理
import signal
signal.signal(signal.SIGCLD, signal.SIG_IGN)

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

chrome_options = webdriver.ChromeOptions()  # 或者 chrome_options = Options()
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])  # 防止反爬
chrome_options.add_argument('--disable-blink-features=AutomationControlled')  # 避免webdriver检测
chrome_options.add_argument("--remote-debugging-port=9222") # 解决报错 WebDriverException: Message: unknown error: DevToolsActivePort file doesn't exist
chrome_options.add_argument('--no-sandbox')  # 直接把sandbox禁用了,–-no-sandbox参数是让Chrome在root权限下跑
chrome_options.add_argument('--disable-dev-shm-usage') # 大量渲染时候写入/tmp而非/dev/shm
chrome_options.add_argument('--headless')  # 无头模式,传递此参数浏览器不会显示界面,程序在后台运行
hrome_options.add_argument('--disable-gpu')  # 禁用GPU加速
chrome_options.add_argument("user-agent='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'") # 模拟浏览器
# chrome_options.add_argument('--proxy-server=http://127.0.0.1:10809')  # 利用v2ray配置代理

driver = webdriver.Chrome(options=chrome_options, service=Service('/usr/local/bin/chromedriver'))
# driver.set_page_load_timeout(300)
driver.maximize_window()  # 仅仅适配到当前显示屏大小,数据偶尔还是不完整,需要下滑鼠标

try:
    driver.get("https://www.163.com")
  
except Exception as e:
    print(e)
else:
    content = driver.page_source.encode('utf-8') # 获取页面响应数据
    print content
finally:
    driver.quit()
​
缺点:需要修改每个相关脚本。

3.2、dumb_init

参照
  • 防止产生僵尸进程的dumb-init程序
  • dumb-init:一个Docker容器初始化系统_语言 & 开发_金灵杰_InfoQ精选文章
制作Dockerfile时可加上此程序,参考docker 中 browserless/chrome 的制作
# It's a good idea to use dumb-init to help prevent zombie chrome processes.
ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 /usr/local/bin/dumb-init
RUN chmod +x /usr/local/bin/dumb-init
然后,要在容器中使用 dumb-init,可以直接安deb 包,或者从 源码构建。容器启动时,使用 dumb-init 作为初始进程,确保所有子进程都由 dumb-init 进程创建:
docker run my_container dumb-init python -c 'while True: pass' 
结果:1号进程是dumb-init
缺点:需要先安装dumb -init才能在docker run时使用dumb -init。

3.3、docker运行时加入--init参数

在docker运行时加入--init参数,这样 docker内1号进程就是docker-init进程,业务进程则是其子进程
docker-init进程会将收到的信号传递给其子进程,并且会处理僵尸进程。
docker run  -it  --init  -v /home/blackip:/home/blackips/ selenium:1.0  python3 linux_black_ip.py
结果:
可以看到1号进程是/sbin/docker-init -- python3 linux_black_ip.py;top查看的僵尸进程zombie为0。

3.4、其他解决办法参考

  • 一次 Docker 容器内大量僵尸进程排查分析 - 番茄系统家园 (nndssk.com)
  • node.js - Kubernetes equivalent of `docker run --init` - Stack Overflow
如果直接使用 docker、docker-compose 就用第一种,如果是 k8s,就用第二种!

四、参考

docker,防止产生孤儿进程和僵尸进程 - 简书 (jianshu.com)

(6条消息) 爬虫服务(chromedp)僵尸进程排查记录_chromedp 僵尸进程_liyunlong41的博客-CSDN博客

dumb-init:一个Docker容器初始化系统_语言 & 开发_金灵杰_InfoQ精选文章

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/424772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微服务+springcloud+springcloud alibaba学习笔记【Ribbon的使用】(4/9)

Ribbon的使用 4/91、Ribbon负载均衡1.1 Ribbon简介1.2 Ribbon功能1.3 使用Ribbon:1.3.1 Ribbon常用负载均衡算法1.3.2 使用Ribbon1.3.3 ribbon的轮询算法原理1.3.4 手写一个负载均衡轮询算法1.3.5 启动服务,测试1、Ribbon负载均衡 1.1 Ribbon简介 Spring Cloud Ribbon是基于N…

Nestjs实战干货-概况-管道-Pipes

管道 带上装饰器 Injectable() 并实现了 PipeTransform 接口的类,就是管道。 管道有 2 个典型的应用场景: 数值转换:将输入的参数转换成目标类型,例如,string to number。 数值校验:对输入的参数进行校验…

记一次 MySQL 主从同步异常的排查记录,百转千回

本文主要内容如下: 一、现象 最近项目的测试环境遇到一个主备同步的问题: 备库的同步线程停止了,无法同步主库的数据更改。 备库报错如下: 完整的错误信息: Relay log read failure: Could not parse relay log even…

一文读懂【Git 工作流】

文章目录一、Git分支管理二、Git日志规范三、Git Flow工作流一、Git分支管理 我们在实际工作中会创建很多分支以便于不同场景下的开发,但是如果没有分支规范就会造成分支杂乱,大家往往也搞不清楚某一个分支是在做什么,下面我们就介绍一下我们…

车企围攻整车OS,这张“新王牌”怎么打?

今年2月23日,梅赛德斯--奔驰发布了打造自有操作系统MB.OS的具体计划,该操作系统将在本年代中期随全新梅赛德斯-奔驰模块化架构(MMA)平台推出,预计2025年用户将能体验到它的强大功能。 据悉,基于覆盖芯片到…

YOLOv8运行参数解读

整理来自yolov8官方文档常用的一些命令行参数,官方文档YOLOv8 Docs yolov8命令行的统一运行格式为: yolo TASK MODE ARGS其中主要是三部分传参: TASK(可选) 是[detect、segment、classification]中的一个。如果没有显式传递,YO…

智慧水务软件-科学系统架构-数字化管理

平台概述 柳林智慧水务软件是以物联感知技术、大数据、智能控制、云计算、人工智能、数字孪生、AI算法、虚拟现实技术为核心,以监测仪表、通讯网络、数据库系统、数据中台、模型软件、前台展示、智慧运维等产品体系为支撑,以城市水资源、水生态、水环境…

VGG论文翻译及复现

VGG网络实现:https://blog.csdn.net/weixin_43912621/article/details/127852595 论文地址:https://arxiv.org/abs/1409.1556 VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION 用于大规模图像识别的深度卷积网络 Abstract In t…

Salesforce Admin管理员中文学习教程,如何高效筛选出具有Admin权限的用户!

组织中最常见的错误之一就是拥有太多具有系统管理员简档的用户。不幸的是,这在某些行业中非常普遍。 实际上这存在着很大的潜在风险。拥有这些权限的用户可能会暴露、窃取或删除组织中的数据,甚至影响到其他用户。防止过多的管理员访问权限是保护Salesf…

基于Python机器学习、深度学习技术提升气象、海洋、水文领域实践应用能力

目录 专题一、Python软件的安装及入门 专题二、气象常用科学计算库 专题三、气象海洋常用可视化库 专题四、爬虫和气象海洋数据 专题五、气象海洋常用插值方法 专题六、机器学习基础理论和实操 专题七、机器学习的应用实例 专题八、深度学习基础理论和实操 专题九、深…

摸鱼也可以效率翻倍:Python 统计 gitlab 代码量,定量统计发给领导

嗨害大家好鸭!我是爱摸鱼的芝士❤ 一、确定需求 需求是公司大领导想要了解每周研发提交的代码量。 因为研发人员比较多, 想着用 python 做个自动化, 定时统计代码量并发送邮件给领导。 二、统计gitlab代码 首先安装第三方库python-gitlab&…

如何提升智能文档处理识别精度?合合信息“版面分析”实现新突破

春季是繁忙的播种季,学生党迎来了开学季和紧张的研究生复试,职场人士也需要处理新签业务带来的大量不同类型的文件,比如合同、发票、档案等。这些文件在被拍照、扫描成电子文档的过程中,时常存在漏字、错位现象。究其原因&#xf…

kali的下载与安装(VM虚拟机)

目录 一、介绍 二、下载安装 (一)官网下载kali (二)官网下载VM虚拟机 (三)安装VM虚拟机 (三)VM虚拟机里面安装kali系统 一、介绍 (1)Kali Linux是一种基…

基于Chatbot UI 实现ChatGPT对话-V1.0

基于Chatbot UI 实现ChatGPT对话-V1.0 前端基于开源项目:chatbot-ui进行二次开发,感兴趣的小伙伴可以自行研究。 本项目搭建初衷:在无法科学上网的情况下,实现ChatGPT对话。还有规避官方聊天时,长时间无链接导致的问题…

“GPT全家桶”,喂不饱商汤科技

加码追风大模型,终究没能让商汤科技找回投资者们的信心。 4月10日,商汤发布了“日日新SenseNova”大模型体系,且一口气展示了多个产品,有类ChatGPT产品“商量”(SenseChat)、与Midjourney画风一致的秒画平台…

语句覆盖率\条件覆盖率\路径覆盖率\分支覆盖率的区别您知道吗

代码覆盖率 代码覆盖率是一种度量,它描述了程序源代码已经过测试的程度,它可以帮助我们评估测试执行的效率, 简单来理解代码覆盖率就是单元测试中代码执行量与代码总量之间的比率。代码覆盖率主要包括语句覆盖率、分支覆盖率、条件覆盖率和路…

【Linux】实现守护进程 | 以tcpServer为例

本文首发于 慕雪的寒舍 本文将以tcp服务器代码为基本,讲述如何将进程守护进程化,后台运行 1.守护进程 所谓守护进程,就是和其他进程没有关系的进程;其独立运行于系统后台,除非自己退出或收到信号终止,否则…

逆向-还原代码之(*point)[4]和char *point[4] (Arm 64)

// source code #include <stdio.h> #include <string.h> #include <stdlib.h> /* * char (*point)[4] // 数组指针。 a[3][4] // 先申明二维数组,用它来指向这个二维数组 * char *point[4] // 指针数组。 a[4][5] // 一连串的指针…

编程语言,TIOBE 4 月榜单:黑马出现了

TIOBE 4 月榜单已经发布了&#xff0c;一起来看看这个月编程语言排行榜有什么变化吧&#xff01; C 发展依旧迅猛 在本月榜单中&#xff0c;TOP 20 的变动不大&#xff0c;Python、C、Java 、 C 和C#依然占据前五。甚至排名顺序都和上个月一样没有变动。 同时&#xff0c;Rus…

【图形学】多边形裁剪算法综述

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本文是个人学习多边形裁剪知识整理的&#xff0c;整理期间努力理解论文作者含义&#xff0c;并增加了自己的详述和注解。 &#x1f970;来源&#xff1a;材料主要源于多边形裁剪相关论文进行的&#xff0c;每个知识点的学习…