Featured image of post 容器中的僵尸进程问题

容器中的僵尸进程问题

1、僵尸进程问题

父进程创建出子进程后,需要回收子进程,回收进程号。

C语言 fork() 出子进程后需要调用 waitwaitpid 方法。回收子进程。wait 会阻塞,waitpid 带 WNOHANG 参数的方法不会阻塞。

例如:使用 tini 作为init进程来管理我们的应用进程,tini 就会调用 waitpid 带 WNOHANG 参数的方法来清理僵尸进程。

在Java中很少去创建子进程来干活,一般都是创建线程,线程比进程轻量级。如下是创建子进程的代码。

1
2
3
4
5
// Runtime在jvm是单例
Runtime runtime = Runtime.getRuntime();
 
// 调用exec创建进程----  process进程对象
Process process = runtime.exec("Java指令");

同样的 Java 中的 Process 也有 wait 相关的方法。

2、限制容器内的进程数量

容器就是一些列的进程集合,容器内的进程是会映射到宿主机的,所以容器不能无限制的创建进程,否则最终会影响到宿主机。在宿主机的目录下(7ecd3aa7fdc15a1e183813b1899d5d939beafb11833ad6c8b0432536e5b9871c是容器id)的pids.max里面写入数字来限制容器内的进程数量。

/sys/fs/cgroup/pids/system.slice/docker-7ecd3aa7fdc15a1e183813b1899d5d939beafb11833ad6c8b0432536e5b9871c.scope

3、思考:init进程创建了b进程,b进程创建了c进程。如果c进程运行完成为了僵尸进程,b进程还在运行,init进程不断 waitpid ,c进程这个僵尸进程会不会被回收?

c进程不会被回收,waitpid 仅会等待直接子进程的状态变化。

为什么进程会进入僵尸进程而不是直接消失,是因为给父进程一次机会查看子进程的pid、终止状态(退出码、终止原因是信号终止还是正常退出等),还有子进程的资源使用情况。如果子进程直接消失那么父进程没有机会知道子进程的终止原因。一般情况下会根据子进程终止情况做出进一步处理。比如 Nginx Master 进程获知 worker 进程异常退出会重新拉起一个 worker 进程。

Licensed under CC BY-NC-SA 4.0