LoginSignup
6
4

More than 1 year has passed since last update.

ゾンビプロセスの自動キル方法

Posted at

きっかけ

以前にAWS SSMを通じて、別サーバからDBを参照できるようにしていました。

そしたらバックグラウンド(nohup)実行のタスクが、ゾンビとして大量に生産され大変なことになっていました... :zap:

こんな感じ
[hoge@hogehost ~]$ ps -ef | grep defunct
root       338   334  0  6月30 ?      00:00:00 [sh] <defunct>
root      3127  3126  0  6月30 ?      00:00:00 [sh] <defunct>
root      5791  5789  0  6月30 ?      00:00:00 [sh] <defunct>
root      8468  8466  0  6月30 ?      00:00:00 [sh] <defunct>
root     11150 11146  0  6月30 ?      00:00:00 [sh] <defunct>
# 以下略 #

defunctとは?

ゾンビプロセス確認には、ps -ef | grep defunctで検索したけどdefunctってなんぞやと思いました。

上記から、

  • プロセスのタスク完了/破損/キルのいずれかの状態
    • だけど、子プロセスとして実行されている
    • もしくは、親プロセスは、該当する子プロセスを監視している

ということを示していることがわかりました。
また、プロセスIDの削除についても親と子の両方のプロセスを殺す必要がわかりました。

kill -9 PID1 PID2

やったこと

  • ゾンビプロセスの自動キル
    • 一応30分ごとに張るセッションを切らないように、1時間経過したゾンビだけを削除
    • 月から金まで、6時間ごとに一括削除
cron
* */6 * * 1-5 ./kill_zombie_process.sh;
zombie_process_kill.sh

#/bin/bash

# REF: https://ex1.m-yabe.com/archives/3490
PName=defunct
PID=$$

for i in `ps -ef | grep $PName | grep -v $PID | grep -v grep | awk '{print $2,$3}'`
do
    TIME=`ps -o lstart --noheader -p $i`

    if [ -n "$TIME" ]; then
        StartupTime=`date +%s -d "$TIME"`
        CurrentTime=`date +%s`
        ElapsedTime=`expr $CurrentTime - $StartupTime`
    else
        ElapsedTime=1
    fi

    # 1時間以上経過したゾンビプロセスは削除する
    if [ $ElapsedTime -gt 3600 ] ; then
        kill -9 $i
    fi  
done

参考

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4