技术开发 频道

清除WAS的僵死进程

        【IT168 技术文章】

       “百足之虫,至死不僵,以扶之者众也。”

                                  ————三国·魏·曹冏《六代论》

    一、背景:僵死进程让人心烦意乱

    在日常的维护中,在紧急情况下需要kill -9杀掉WAS的进程后,WAS会自动重启server,但是与此同时你又在管理控制台重启server,因为WAS在:进程定义-监控策略的常规属性条目“自动重新启动”选项默认情况下是自动选中的,也就是说其“指定如果进程失败了是否应该自动重新启动。缺省为自动重新启动进程。”由于重复重启,后启动的进程一般会抛出“已经有同样的实例在运行或者端口冲突”的错误信息,重启无效的同时不会自动停止而导致操作系统层面产生很多无用但是又占微量CPU和几百M内存的垃圾进程,我一般习惯称之为僵死进程。

    上述讨论了我理所当然认为WAS会产生僵死进程的一种典型场景,当然还有其他情形也有可能,大家可以加以发挥。

    二、目标:对待垃圾要一扫为快

    “百足之虫,至死不僵”,如何漂亮地处理这种光占坑不拉屎的同志,最好是一除为快。本篇通过shell以短平快的方式迅速为操作系统尽微薄之力:

    1、洗胃清肠,清理垃圾,减轻负担,提高性能;

    2、解决在top命令看到一堆进程任务在屏幕妖光闪闪,但实际WAS的server又没几个在跑、分不清孰友孰敌情形下,有效减少视野污染。

    三、实战:举手之劳写个脚本搞定

    设计思路简单提要如下:

    1、获取跟WAS相关的dmgr、nodeagent、server的运行时有用进程;

    2、获取跟其他应用相关的运行时进程,to do,自行加码;

    3、获取所有运行时有用的WebSphere JAVA进程的进程号集合;

    4、获取与WebSphere有关的JAVA进程集合;

    5、获取待杀的与WebSphere有关的JAVA垃圾进程集合(采用排除法,即,一个进程要么是有用的,要么是垃圾,没有第三种选择);

    6、杀掉待杀的与WebSphere有关的JAVA垃圾进程;

    闲话少说,静心看代码,代码有注释,千言万语尽在行行复行行的百行代码之内。

    #!/bin/sh

    #      getridofzombie4java.sh

    #目的:清理WAS因kill -9而产生的、以及其他原因产生的java僵死进程

    #作者:carpnet

    #日期:2008-08-15

    #更新:2009-04-27

    #WAS_INSTALL_HOME

    WAS_INSTALL_HOME="/IBM/WebSphere"

    #WAS的*.pid文件里记录的进程号集合

    wasppids=""

    #以WAS的*.pid的进程号为父进程及其自身的所有进程号集合

    allwaspids=""

    #其他应用相关的运行时进程号集合

    otherapppids=""

    #所有运行时有用WebSphere JAVA进程的进程号集合

    persistpids=""

    #存放所有运行时有用WebSphere JAVA进程的进程号集合的临时文件

    persistpidstmp="$WAS_INSTALL_HOME/persistpids.tmp"

    cat /dev/null > $persistpidstmp

    #与java有关的进程集合

    javapids=""

    #待杀的垃圾进程集合

    killedpids=""

    ##1.获取跟WAS相关的dmgr、nodeagent、server的运行时进程

    #获取WAS的*.pid文件的绝对路径

    waspidstr=`find $WAS_INSTALL_HOME -name *.pid|awk '{ORS=" "}{print $1}' `

    echo "[`date`] WAS的*.pid文件列表为:$waspidstr"

    #获取以*.pid的进程号为父进程及其自身的所有进程号

    if [ "$waspidstr" != "" ]

    then

        for per in $waspidstr

        do

            waspid="`cat $per`"

            echo "[`date`] $per的进程号为:$waspid"

          

            subwaspids=`ps -ef|grep root|grep WebSphere|grep java|grep $waspid|grep -v grep|awk '{ORS=" "}{print $2}' `

            echo "[`date`] 以$waspid为父进程的子进程有:$subwaspids"

            wasppids="$waspids $waspid"

            allwaspids="$allwaspids $subwaspids"

        done

    fi

    echo "[`date`] 以$wasppids为父进程及其自身的所有进程号集合有:$allwaspids"

    ##2.获取跟其他应用相关的运行时进程,to do

    ##3.获取所有运行时有用的WebSphere JAVA进程的进程号集合

    persistpids="$allwaspids $otherapppids"

    echo "[`date`] 所有运行时有用的WebSphere JAVA进程的进程号集合有:$persistpids"

    ##4.获取与WebSphere有关的JAVA进程集合

    javapids=`ps -ef|grep root|grep WebSphere|grep java|grep -v grep|awk '{ORS=" "} {print $2}' `

    echo "[`date`] 与WebSphere有关的JAVA进程集合为:$javapids"

    ##5.获取待杀的与WebSphere有关的JAVA垃圾进程集合

    if [ "$javapids" != "" ] && [ "$persistpids" != "" ]

    then

        echo "$persistpids" > $persistpidstmp

        for javapid in $javapids

        do

            inflag=`grep $javapid $persistpidstmp|wc -l`

          

            if [ $inflag -eq 0 ]

            then

                killedpids="$killedpids $javapid"

            fi

        done

        rm -rf $persistpidstmp

    fi

    echo "[`date`] 待杀的与WebSphere有关的JAVA垃圾进程集合为:$killedpids"

    ##6.杀掉待杀的与WebSphere有关的JAVA垃圾进程

    if [ "$killedpids" != "" ]

    then

        echo "[`date`] 待杀的与WebSphere有关的JAVA垃圾进程集合非空,进入扑杀状态!"

        exit 0

        kill -9 $killedpids

    else

        if [ "$killedpids" = "" ]

        then

            echo "[`date`] 待杀的与WebSphere有关的JAVA垃圾进程集合为空,所以无以为杀!"

        fi

    fi

    echo "[`date`] 完成扑杀的与WebSphere有关的JAVA垃圾进程!"

    exit 0

    以上shell脚本已经在HP UX以及Redhat Linux上验证通过。

    尤为需要注意的是,如果机器上不仅安装了WAS,同时还有其他应用的话,请自行完善“2、获取跟其他应用相关的运行时进程,to do,自行加码;”捕捉到其他应用的在用进程,避免错杀好人,否则枉杀无辜,后果自负。
 

0
相关文章