|
Answer» Hi Everyone, Firstly thx for reading this and if you can help, please i'd REALLY appreciate it... :-) (I did search for a similar topic but could not find anything)
1. THE PROBLEM --------------------
I have a VPS running about 10-15 applications. All the apps (all with the same image name) use only about 25-40MB each or at least they should but it seems lately that one balloons to about 350MB plus over about 12+ hours for no apparent reason and this affects the entire Server as you could imagine.
I am rebooting every 24 hours (automated of course) which helps a h#ll of a lot. I also have a service running that reboots if the memory BECOMES too low. All of this is great and does help but I still have too much downtime because the reboots take about 5 minutes roughly before these applications are started up again. I NEED a more intelligent solution.
I am running MS Windows Server 2003 Enterprise x64 SP2 on the VPS. The VPS has no virtual memory so it is all strictly 'RAM' so when it falls over it really falls over.
2. THE SOLUTION ?? -----------------------
I have written a batch file that just kills all these applications [ taskkill /f /IM XxXxX.exe ] and then I have a seperate .bat file to start them all again. I could schedule both to run every 2 hours or so and it would kill everything and then start it up. However, that is not a very smart way to solve the problem, far smarter would be to have some kind of background monitor that will kill THE PROBLEM application if its memory size execeeds a certain value (about 50MB in my case would be perfect). Obviously after killing it and checking that it is 'dead' it would then start the app again. All the other apps would continue running unafftected and only the ONE app would be down for about 10-15 seconds.
So in summary (sorry for too much detail) I need assistance in writing a windows batch file (.bat) to kill a specific process (and then start it up again) if it exceeds a certain amount of memory - 50MB should be fine.
If this works I would also only need to schedule a reboot once every 2-3+ days probably which would be a further improvement to my situation.
All these apllications have the same "Image Name" but obviously a differend PID (Process ID) so what would solve my problem is a some kind of background process or bat file that every 15 minutes or so checks to see if a process with imagine name XxXxX.exe exceeeds a total memory footprint of 50MB. If this PID does exceed 50MB then kill it and start it up again once it has checked it is dead.
I'm sure somebody has had a problem like this before so I'm hopeful somebody can assist me with wrting a bat file that can do some IF this PID's mem >= 50MB THEN kill bla bla statements (I don't know how to do that) or perhaps there is FREE software that could ckeck this. I would even consider paying for something if not too pricy. I think a .bat file would be best because my situation is fairly unique and other processes are allowed to exceed 50MB.
THX for reading all this !!
Configuration: MS Windows Server 2003 Enterprise x64 SP2 on a Virtual Private Server (VPS)Code: [Select]@echo off setlocal enabledelayedexpansion
set appNameArr= call :makeArr
set maxUsg=50 000 REM In KB / Space must be there
set waitTime=1 REM In Sec
set /a waitTime=%waitTime%*1000
:LOOP for %%a in (%pidArr%) do ( for /f "tokens=1-5 delims= " %%b in ('tasklist ^|findstr "%%a"') do ( if %%c equ %%a (
set appUsg=%%f set appUsg=!appUsg:KB=!
if "!appUsg!" gtr "!maxUsg!" (taskkill /F /PID %%a & echo %%b RamLimit exceed... Closing...) ELSE (echo %%b RamUsage !appUsg!) ) ) )
ping -n 1 -w %waitTime% 1.1.1.1 >nul goto LOOP
:makeArr for %%a in (%appNameArr%) do ( for /f "tokens=1-2" %%b in ('tasklist ^|findstr %%a') do ( set pidArr=!pidArr! %%c ) )
exit /b here is code but i dont know how to start app after killing
EDIT:
changed taskkill /IM to taskkill /PID :-) THANKS SOO MUCH devcom
- only had a few minutes to test this so I can't say for sure it'll suit my purposes but SO FAR THIS IS BRILLIANT. works 100% - must just try try it with multiple identical image names
QUESTION: Is there anyway to get the exact PATH and FILENAME of the app that was KILLED so it can be started up again. E.G. If it killed the image name taskmgr.exe it would get the full command line argument and save it to a variable for later use: e.g. ARG would be : "c:\WINDOWS\system32\taskmgr.exe"
I could then just run that command after it's killed and it would start fresh and new again with low memory footprint.
I have attached a screenshot of an alternative task manager type app - it's called "Process Explorer" (free app by the way if anybody likes the look of it) - it lists the 'Command Line path' of the proccesse so I just need help trying to figure out how to get the 'Command Line path' of the app that EXCEEDED too much RAM in my batch script so I can start it up again.
Does anybody know know how I can get that using a batch script?
Thanks again devcom - this works brilliantly :-)
[attachment deleted by admin]I have tested it more thoroughly now and it works 100% - I just need some help in starting it up again once it's been killed.
Does anbody know how to extract the 'Command Line path' of the process before it's killed so I can start it again afterwards?WMIC PROCESS get Commandline seems to work. I just need to figure out how to specify for a specific PID. Can anybody help with that?Code: [Select]C:\>if "900" gtr "2 000" echo invalid equation invalid equation
C:\>if "1.000.000" gtr "50 000" (echo correct) else echo invalid equation invalid equationCode: [Select]@echo off setlocal enabledelayedexpansion
set appNameArr=cmd.exe gg.exe
for %%a in (%appNameArr%) do (
set /a num+=1 for /f "tokens=*" %%b in ('wmic process get Name ^|findstr "%%a"') do (set /a nameNum+=1 & set name_!namenum!=%%b) for /f "tokens=1-2 delims= " %%c in ('wmic process get Name^,ProcessId ^|findstr "%%a"') do (set /a pridNum+=1 & set prid_!pridnum!=%%d) for /f "tokens=*" %%e in ('wmic process get ExecutablePath ^|findstr "%%a"') do (set /a pathNum+=1 & set path_!pathnum!=%%e)
) pause set maxNum=%namenum% set num=0
set maxUsg=50 000 REM In KB / Space must be there
set waitTime=1 REM In Sec
set /a waitTime=%waitTime%*1000
:LOOP for /L %%a in (1,1,%maxNum%) do (
call set tmpa=%%name_%%a%%% call set tmpb=%%prid_%%a%%% call set tmpc=%%path_%%a%%%
for /f "tokens=1-5* delims= " %%b in ('tasklist ^|findstr "!tmpa!"') do (
if %%c equ !tmpb! (
set appUsg=%%f set appUsg=!appUsg:KB=!
if "!appUsg!" gtr "!maxUsg!" ( taskkill /F /PID !tmpb! echo !tmpb! RamLimit exceed... Restart... Name: !tmpa! start "" "!tmpc!"
REM 1 sec to start up app ping -n 1 -w 1000 1.1.1.1 >nul ) ELSE (echo !tmpb! RamUsage !appUsg! Name: !tmpa!)
) ) )
ping -n 1 -w %waitTime% 1.1.1.1 >nul goto LOOP this should do the work
|