公司的erp主机因 licence数量有限,近来经常发生用户超限,不能连接. 其实很多用户都是将系统连接上,半天也不用,这无形中造成很大的浪费. 资源分配造成不合理的现象.想用的人连接不上,不用系统的人却连接在系统上. 神码提供了一个shell,不过执行效率上有点慢.每次一运行系统就变得很慢. cpu就会冲到90--100%,会执续20分钟. 我将它作了一些改动,效率提高了不少.时间现在基本上都在5分钟内就完成了,cpu 也不会冲到很高.呵呵还是有点成就的 ^_^
以下是shell的内容:
====================================================== #!/bin/ksh INFORMIXSERVER=on_shm01;export INFORMIXSERVER ONCONFIG=onconfig.on_01;export ONCONFIG DB_LOCALE=zh_tw.big5;export DB_LOCALE SERVER_LOCALE=zh_tw.big5;export SERVER_LOCALE CLIENT_LOCALE=zh_tw.big5;export CLIENT_LOCALE LANG=zh_tw.big5;export LANG
echo "INFORMIXSERVER=$INFORMIXSERVER" echo "ONCONFIG=$ONCONFIG"
INFORMIXDIR=/u1/informix;export INFORMIXDIR PATH=$INFORMIXDIR/bin:$PATH;export PATH DBDATE=Y4MD/;export DBDATE DBCENTURY=C;export DBCENTURY DBDELIMITER='^A';export DBDELIMITER
if [ $# -ne 1 ] then echo "Usage: killidle.sh idletime " echo "Ex: killidle.sh 1800 " echo " (R idle WL 30 informix Session )" echo " (R?: informix Sesion S?gg?@WL???)" exit fi idle= now=`date | awk '{ print }'` kill_time=`date '+%y/%m/%d-%H:%M:%S'` echo "?:$kill_time" tsNow=0 hhn=`echo $now | cut -d':' -f 1` mmn=`echo $now | cut -d':' -f 2` ssn=`echo $now | cut -d':' -f 3` tsNow=`expr $hhn \* 3600 + $mmn \* 60 + $ssn`
ToSec() { # : opentime hh1=`echo | cut -d':' -f 1` mm1=`echo | cut -d':' -f 2` ss1=`echo | cut -d':' -f 3` ts1=`expr $hh1 \* 3600 + $mm1 \* 60 + $ss1 ` # : writetime hh2=`echo | cut -d':' -f 1` mm2=`echo | cut -d':' -f 2` ss2=`echo | cut -d':' -f 3` ts2=`expr $hh2 \* 3600 + $mm2 \* 60 + $ss2 ` if [ ts1 -gt ts2 ] then ts=`expr $tsNow - $ts1` else ts=`expr $tsNow - $ts2` fi #echo $ts }
i=0 cnt=1 sesID="" opnetime="" readtime="" writetime=""
#X?sW informix sesion onstat -g ses > t1.tmp tail +6 t1.tmp>ifx_u.tmp rm t1.tmp ps -ef|awk '{print }' > ps_ef.tmp
#dX? session su? for f in `onstat -g ntt | grep sqlexec | awk '{ print ,,, }'` do i=`expr $i + 1` case $i in 1) sesID=$f ;; 2) opentime=$f ;; 3) readtime=$f ;; 4) writetime=$f ToSec $readtime $writetime # echo "Session ID:$sesID , opentime:$opentime , readtime:$readtime , writetime:$writetime , idle time:$ts Sec. " if [ $ts -gt $idle ] # pGWL idle time then echo "$cnt)SeID:$sesID,OTime:$opentime,RTime:$readtime,WTime:$writetime,IdleTime:$ts Sec." while read L1 do t_ses=`echo $L1 | awk '{ print }'` # echo "$L1,t_ses is: $t_ses -sesID is :$sesID" if [ $t_ses -eq $sesID ] then t_uname=`echo $L1 | awk '{ print }'` # session woner t_kill=`grep $t_uname $INFORMIXDIR/top_nokill.list | grep -v grep | wc | awk '{ print }'` if [ t_kill -eq 0 ]; # pGb top_nokill.list,NnR then t_pid=`echo $L1 | awk '{ print }'` ## t_pid_no=`ps -ef | grep $t_pid | grep -v grep | wc | awk '{ print }'` t_pid_no=`grep $t_pid ps_ef.tmp|wc -l` t_tty=`echo $L1 | awk '{ print "pts/", }' | tr -d ' '` t_host=`echo $L1 | awk '{ print }'` kill_time=`date '+%H:%M:%S'` if [ $t_pid_no -eq 1 ] then echo "Kill:PID:$t_pid,Uname:$t_uname,Tty:$t_tty,pid_no:$t_pid_no,time:$kill_time"
onmode -z $t_ses kill -9 $t_pid else echo "Keep(1):PID:$t_pid ,Uname:$t_uname ,tty:$t_tty,pid_no:$t_pid_no"
fi else echo "Keep(2):PID:$t_pid ,Uname:$t_uname ,tty:$t_tty" fi break; fi done < ifx_u.tmp cnt=`expr $cnt + 1` fi i=0;; esac done kill_time=`date '+%y/%m/%d-%H:%M:%S'` echo "?:$kill_time" rm ifx_u.tmp rm ps_ef.tmp
. /u1/fgl2c.run/envcomp fglWrt -u
##############################################
将此shell放入到crontab中 每半小时执行一次,这样基本上半小时不用系统的用户,就被kill了 注意此shell一定是由root来执行的,因为只有root能kill别人的pid号 以下是我的crontab中的内容:在上班时间每半小时执行一次此shell.并将相应的log保存到killidle.log文件中. # crontab -l 0,30 8,9,10,11,12,13,14,15,16,17 * * * sh /u1/informix/killidle.sh 1800 >>killidle.log 2>&1
#后计: 此shell在配合tiptop erp执行上还是有点问题,因为tiptop的主画面也要占用一个数据库连接,而如果跑一个长一点的程序 如mrp或财务结算成本的程序,因为这些程序都是tiptop主画面进程的子进程,在作killidle判断时并不会结合几个进程一起来作. 也就是说,如果要kill主程序进程时,不会考虑它是否还有子进程在运行,且子进程的数据库访问时间没有超过idle时间.而是直接将主 进程kill了,从而造成在跑这些长程序时有误kill的情况. 目前正在改进这个方面,流程基本上出来了,代玛写的差不多了,不过感觉这样一来逻辑上太复杂,程序执行上会很慢,而且执行长程序的 时间不是很频繁,所以在想要不要将它再写下去.
| | |