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

这篇具有很好参考价值的文章主要介绍了解决 Docker + selenium + chromedriver + chrome 会出现僵尸进程的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、僵尸进程问题

在docker里,使用selenium爬虫,  webdriver quit后,会产生很多僵尸进程。
docker run  - it  - v / home / blackip :/ home / blackips /   selenium : 1.0   python3 linux_black_ip . py
top查看僵尸进程:
解决 Docker + selenium + chromedriver + chrome 会出现僵尸进程的问题
ps -ef | grep defunct查看僵尸进程:
解决 Docker + selenium + chromedriver + chrome 会出现僵尸进程的问题
僵尸进程的父进程是python3。
看了下chrome运行时的状况,发现开始的父进程并不是1,但到最后都变成了1,并且变为defunct状态:
ps -ef | grep chrome| grep -v defunct
解决 Docker + selenium + chromedriver + chrome 会出现僵尸进程的问题
超多的僵尸进程会耗尽 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
解决 Docker + selenium + chromedriver + chrome 会出现僵尸进程的问题
缺点:需要先安装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
结果:
解决 Docker + selenium + chromedriver + chrome 会出现僵尸进程的问题
解决 Docker + selenium + chromedriver + chrome 会出现僵尸进程的问题
可以看到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精选文章文章来源地址https://www.toymoban.com/news/detail-423619.html

到了这里,关于解决 Docker + selenium + chromedriver + chrome 会出现僵尸进程的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Selenium】chromedriver新版本与Chrome自动更新版本不匹配问题

    python代码运行出现如下错误:This version of ChromeDriver only supports Chrome version 114 Current browser version is 116.0.5845.141 with binary path C:Program FilesGoogleChromeApplicationchrome.exe 解决方案: 1.查看当前Google浏览器版本:版本 116.0.5845.141(正式版本) (64 位) 2.下载对应的浏览器驱动chromed

    2024年02月08日
    浏览(51)
  • 【Selenium】chromedriver最新版本与Chrome自动更新版本不匹配问题

    使用Selenium时需要下载chromedriver 1、首先查看我的Chrome浏览器版本已自动更新到116: 2、查找与之对应的chromedriver版本:http://chromedriver.storage.googleapis.com/index.html 发现最新版本只到114: chromedriver与Chrome版本不匹配且没有匹配最新Chrome版本的chromedriver。 因此考虑降级Chrome版本且

    2024年02月16日
    浏览(66)
  • linux下安装 Chrome 和 chromedriver 以及 selenium webdriver 使用

    chromedriver 下载地址: https://googlechromelabs.github.io/chrome-for-testing/ (推荐,包含最新稳定版) https://chromedriver.storage.googleapis.com/index.html? http://npm.taobao.org/mirrors/chromedriver/ https://registry.npmmirror.com/-/binary/chromedriver/ 查看版本: chromedriver对应下载地址 现在就可以使用 selenium 的 web

    2024年02月08日
    浏览(75)
  • Selenium 与(Firefox、GeckoDriver)和(Chrome、ChromeDriver)版本对应关系

    找了一圈,竟然一个靠谱的版本对应表都找不到,这里整理一下 Selenium ChromeDriver Chrome GeckoDriver Firefox 文档地址:Geckodriver Supported platforms geckodriver Selenium Firefox 0.32.0 ≥ 3.11 (3.14 Python) 102 ESR - n/a 0.31.0 ≥ 3.11 (3.14 Python) 91 ESR - n/a 0.30.0 ≥ 3.11 (3.14 Python) 78 ESR - 90 0.29.1 ≥ 3.11 (3.14

    2024年01月18日
    浏览(45)
  • Selenium根据Chrome浏览器版本自动下载/更新驱动chromedriver.exe

    个人经常使用到 selenium 来控制浏览器进行相关的操作,但是 Chrome浏览器 经常会自动更新,导致已有的 驱动程序chromedriver.exe 失效,需要重新下载。 以前尝试过禁止Chrome浏览器更新,但是这并不是很好的解决方案。 于是换了个方向,既然Chrome浏览器会自动更新,那么在我使

    2024年02月09日
    浏览(78)
  • 关于selenium, 你还在因为chromedriver的版本与Chrome的版本不一致,需要手动更新chromedriver而烦恼吗?

    平时做爬虫我比较喜欢用 selenium chrome ,一直困扰我一个问题,就是只要谷歌浏览器更新了,就要重新去下载对应版本的 chromedriver_win32 ,这让我十分烦恼 比如我的谷歌浏览器已经94版本了,但是 chromedriver_win32 还停留在92版本,就会报出下面的错误 selenium.common.exceptions.SessionN

    2024年02月12日
    浏览(44)
  • CentOS7 启动谷歌浏览器 java+Selenium+chrome+chromedriver

    前言:自己想使用该技术实现自动化抓取音乐,目前在window上运行成功,需要在Linux Centos服务上跑,配置上出现了许多问题,特此记录。 参考文档:CentOS7 安装Selenium+chrome+chromedriver+java_远方丿的博客-CSDN博客  我们明确的是,在window上是安装了chrome和自带了chromeDriver的,之所

    2024年02月11日
    浏览(125)
  • 使用selenium,但chrome无法启动,需要安装浏览器对应版本(最新)的chromedriver

    使用selenium无法启动chrome,代码 报错如下: 安装地址 查询了浏览器版本:117.0.5927 但是国内的镜像网找不到,只更新到114版本 需要安装驱动,点击了最下面的网址 https://chromedriver.chromium.org/home 如图为有效信息 - 点击跳转: https://googlechromelabs.github.io/chrome-for-testing (点击这里

    2024年02月11日
    浏览(74)
  • chromedriverUnable to obtain driver for chrome using ,selenium找不到chromedriver

    1、下载chromedriver chromedriver下载网址:CNPM Binaries Mirror 老版本在:chromedriver/ 较新版本在:chrome-for-testing/  2、设置了环境变量还是找不到chromedriverUnable to obtain driver for chrome using  方法: 第一种:chromedriver.exe复制文件放入python安装目录的Scripts文件夹中 例如:C:Users***AppDat

    2024年04月28日
    浏览(40)
  • Linux CentOS7安装chrome和chromedriver(WebDriver),用于selenium爬虫(java代码演示)

    序号 产品 版本 备注 1 CentOS 7.9 2 chrome 99.0.4844.51 chrome 与 ChromeDriver 的版本必须一致 3 ChromeDriver 99.0.4844.51 chrome 与 ChromeDriver 的版本必须一致 4 selenium 4.12.1 4 JAVA 8 1.1.1. chrome 下载 点击 chrome历史版本下载,按步骤下载 从下载的压缩包解压出rpm,上传 CentOS 系统 1.1.2. chrome 安装 安

    2024年02月20日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包