docker,防止产生孤儿进程和僵尸进程

在docker中使用selenium 或者pyppeteer,browser退出后,会产生僵尸进程。

处理方法一:

脚本内部加入信号处理的方法,参照文章https://www.jianshu.com/p/160a401eabb4

在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN,这样,内核在子进程结束时不会产生僵尸进程。python 可以调用singal包来处理。

signal包的核心是使用signal.signal()函数来预设(register)信号处理函数:
参照:1. Python模块之信号(signal)2.Python Signal(信号) 异步系统事件

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)

def screenshot(url):
    current_path = os.path.join(os.path.dirname(__file__))  # 文件的暂存路径
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--disable-dev-shm-usage')
    browser_exe_path = os.path.join(current_path, "chromedriver")
    browser = webdriver.Chrome(executable_path=browser_exe_path,
                                   chrome_options=chrome_options)
    browser.get(url)
    time.sleep(5)
    size = browser.find_element_by_xpath("//main").size
    browser.set_window_size(1200, size.get("height"))
    pic_path = os.path.join(current_path, "screenshot.png")
    browser.save_screenshot(pic_path)
    browser.quit()
if __name__=='__main__':
    url='https://www.baidu.com'
    screenshot(url)

处理方法二:

别人写好的程序,下载启动,参照:防止产生僵尸进程的dumb-init程序

dumb-init runs as PID 1, acting like a simple init system. It launches a single process and then proxies all received signals to a session rooted at that child process.

Since your actual process is no longer PID 1, when it receives signals from dumb-init, the default signal handlers will be applied, and your process will behave as you would expect. If your process dies, dumb-init will also die, taking care to clean up any other processes that might still remain.

制作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

或者启动命令时
docker run my_container dumb-init python -c 'while True: pass' 参考https://www.infoq.cn/article/2016/01/dumb-init-Docker

你可能感兴趣的:(docker,防止产生孤儿进程和僵尸进程)