zoukankan      html  css  js  c++  java
  • 父进程是1号进程产生大量的僵尸进程的解决方案

    实际记录一次在使用Dockerfile构建镜像和容器的时候出现的问题

    前景:

    封装chrome和crawler进行一个简单的爬虫功能

    Dockerfile的EntryPoint是java -jar 启动jar命令,当你访问api的时候会使用Runtime.exec()方法拼装url自动进行爬取访问。

    定位问题:

    调用chrome会出现大量的chrome进程,同时任务结束的时候调用ps -aux 发现大量的进程stat状态为Z,也就是处于僵尸状态,调用ps -ef 发现僵尸进程的父进程Id为1

    学习过程:

    僵尸进程:stat状态为Z,已经调用过exit方法,但是还是占用一部分的系统资源无法释放。一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit, 它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。

    kill 命令:kill -9 向进程发送结束命令,让进程调用exit方法来进行结束。

    我在学到这两个东西的时候以为我可以使用kill来对僵尸进程进行清理,但是我多次尝试并没有成功,最后发现僵尸进程已经处于死亡状态了,kill没办法再次杀死这个进程了。继续学习

    僵尸进程产生的原因:子进程执行完毕留下了一个需要父进程收尸的一个退出状态结构,如果他的父进程没安装 SIGCHLD 信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态,如果父进程也结束了,这些子进程会自动过继给init进程进程定期的回收。

    学到这里以为搜索网上的处理方法,发现大多的都是让我杀死僵尸进程的父进程,过继给init进程进行回收,但是我发现他们的父进程就是init进程,这可把我整懵了,开始思考

    思考过程:

    容器重启:docker创建的容器会自动将启动的cmd或者enterpoint作为init进程,所以你想要杀死这个进程就必须将整个容器重启,但是我又不想重启整个容器,因为这样我虽然能解决一些问题,但是我相当于是走了一个捷径并没有解决根本问题。

    继续思考,既然我杀不死这些僵尸进程,那我就只能从源头解决了,那就是不让父进程生成僵尸进程,然后我就懵了,因为chrome的默认命令产生的僵尸进程,我也不能修改chrome源码啊!

    寻求帮助:

    在我向公司的大佬提出问题的时候大佬向我提出了一个叫tini的东西

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

    使用方法地址里面已经有了,可以说是非常好用直接解决所有问题,但是我发现他好像在我的执行命令里面增加一些进程。然后fock()出来的都是他的子进程,所以只要直接管理他们的父进程然后回收这些子进程就可以了。原理我也不太懂,慢慢了解,学习的路程永远是快乐的。

  • 相关阅读:
    了解 NoSQL 的必读资料
    关于什么时候用assert(断言)的思考
    这次见到了一些大侠
    NetBeans 时事通讯(刊号 # 87 Jan 12, 2010)
    动态链接库dll,静态链接库lib, 导入库lib
    新女性十得 写得了代码,查得出异常
    记录系统乱谈
    新女性十得 写得了代码,查得出异常
    fullpage.js禁止滚动
    RunningMapReduceExampleTFIDF hadoopclusternet This document describes how to run the TFIDF MapReduce example against ascii books. This project is for those who wants to experiment hadoop as a skunkworks in a small cluster (110 nodes) Google Pro
  • 原文地址:https://www.cnblogs.com/frank9571/p/14327718.html
Copyright © 2011-2022 走看看