公司的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的情況. 目前正在改進這個方面,流程基本上出來了,代瑪寫的差不多了,不過感覺這樣一來邏輯上太複雜,程序執行上會很慢,而且執行長程序的 時間不是很頻繁,所以在想要不要將它再寫下去. |