![自动终止随着时间的推移使用 95% 以上资源的进程?Ubuntu](https://linux22.com/image/1237970/%E8%87%AA%E5%8A%A8%E7%BB%88%E6%AD%A2%E9%9A%8F%E7%9D%80%E6%97%B6%E9%97%B4%E7%9A%84%E6%8E%A8%E7%A7%BB%E4%BD%BF%E7%94%A8%2095%25%20%E4%BB%A5%E4%B8%8A%E8%B5%84%E6%BA%90%E7%9A%84%E8%BF%9B%E7%A8%8B%EF%BC%9FUbuntu.png)
我不知道你的电脑怎么样,但当我的电脑正常工作时,没有任何进程会随着时间的推移消耗 95% 以上的资源。我希望有一些安全措施可以杀死任何有这种行为的进程。我之所以想到这一点,是因为当我今天早上醒来时,我的笔记本电脑已经整晚都在处理一个流浪的 Chromium 子进程。
这可能可以作为 cron 作业来完成,但在我将其作为全职工作来创建这样的工作之前,我认为我应该在这里检查一下。:) 我讨厌重新发明轮子。
答案1
其他人也遇到过这个问题,虽然 Ubuntu 似乎没有内置任何预防机制,但还是有一些想法关于如何改进这一点。
有一个类似的Serverfault 问题提到监控也许能有所帮助。
答案2
我已经创建了一个脚本,终止进程,如果 CPU 使用率在 YY 秒内大于 XX%,则杀死数组中列出的某些进程,或者杀死运行时间超过 ZZ 秒的进程。
- 您可以在文件顶部设置XX,YY,ZZ。
- 您可以使用 ps 或 top 来检查进程。
- 还有一种试运行模式,用于检查但不会杀死。
- 最后,如果某些进程被终止,脚本会发送一封电子邮件。
笔记:这是我在 Github 上的仓库:https://github.com/padosoft/kill-process
脚本的基本部分(top命令的代码摘要):
#!/usr/bin/env bash
#max cpu % load
MAX_CPU=90
#max execution time for CPU percentage > MAX_CPU (in seconds 7200s=2h)
MAX_SEC=1800
#sort by cpu
SORTBY=9
#define a processes command name to check
declare -a KILLLIST
KILLLIST=("/usr/sbin/apache2" "/usr/bin/php5-cgi")
#iterate for each process to check in list
for PROCESS_TOCHECK in ${KILLLIST[*]}
do
#retrive pid with top command order by SORTBY
PID=$(top -bcSH -n 1 | grep $PROCESS_TOCHECK | sort -k $SORTBY -r | head -n 1 | awk '{print $1}')
CPU=$(top -p $PID -bcSH -n 1 | grep $PROCESS_TOCHECK | sort -k $SORTBY -r | head -n 1 | awk '{print $9}')
TIME_STR=$(top -p $PID -bcSH -n 1 | grep $PROCESS_TOCHECK | sort -k $SORTBY -r | head -n 1 | awk '{print $11}')
# Decode the top CPU time format [dd-]hh:mm.ss.
TIME_SEC=0
IFS="-:" read c1 c2 c3 c4 <<< "$TIME_STR"
#with top command time format is hh:mm.ss, so truncare seconds in c2
c2=${c2%%.*}
if [ -n "$c4" ]
then
TIME_SEC=$((10#$c4+60*(10#$c3+60*(10#$c2+24*10#$c1))))
elif [ -n "$c3" ]
then
if [ "$CMD" = "ps" ]; then
TIME_SEC=$((10#$c3+60*(10#$c2+60*10#$c1)))
else
TIME_SEC=$(((10#$c3*24)*60*60)+60*(10#$c2+60*10#$c1))
fi
else
if [ "$CMD" = "ps" ]; then
TIME_SEC=$((10#0+(10#$c2+60*10#$c1)))
else
TIME_SEC=$((10#0+60*(10#$c2+60*10#$c1)))
fi
fi
#check if need to kill process
if [ $CPU -gt $MAX_CPU ] && [ $TIME_SEC -gt $MAX_SEC ]; then
kill -15 $PID
fi
done
用法:
bash killprocess.sh [dry|kill|--help] [top|ps] [cpu|time]
答案3
前段时间,我为我的大学课程编写了一个脚本,用于控制系统资源(CPU 和/或 RAM)的使用。您可以通过在脚本启动时编辑变量来轻松更改最大禁止使用量。脚本应在后台启动,如下所示:
nohup ./auto_killer.sh &
脚本每 N 秒查找一次使用过多资源的进程。如果某个进程使用过多资源,运行该进程的用户会在控制台上收到警告消息。如果连续两次发现同一个进程,则会将其终止(并且用户会收到有关它的信息)。
以下是代码:
#!/bin/bash
Check_Repeating_Time=3; # in seconds
Max_CPU_Usage='25.0'; #%
Max_RAM_Usage='2.0'; #%
Log_Path='/var/log/auto_killer_log'; # path to file when killing logs will be writed
while [ 1 ]; do
ps -aux |
awk '{
Username = $1;
Proc_Name = $11;
CPU_Usage = $3;
RAM_Usage = $4;
PID = $2;
TTY = $7;
if((CPU_Usage >= '$Max_CPU_Usage' || RAM_Usage >= '$Max_RAM_Usage' ) && !($1 == "USER" || $1 == "root" || $1 == "daemon" || $1 == "mysql" || $1 == "avahi" || $1 == "polkitd"))
{
Func_Num_of_Ocur = "cat ./auto_killer_data | grep "PID" | wc -l";
Func_Num_of_Ocur |getline Str_Num_Of_Ocur;
if(Str_Num_Of_Ocur == "0")
{
system ("echo \"\" >> /dev/" TTY);
system ("echo \"Process "Proc_Name" used to much of resources. It will be killed in '$Check_Repeating_Time' seconds if it wont stop!\" >> /dev/" TTY );
system ("echo \"\" >> /dev/" TTY);
system ("echo "PID" >> ./auto_killer_data.new");
}
else
{
system ("echo \"\" >> /dev/" TTY);
system ("echo \"Process "Proc_Name" was killed because it used to much of system resources!\" >> /dev/" TTY );
system ("echo \"\" >> /dev/" TTY);
system ("kill -9 " PID);
Data = "date";
Data |getline Str_Data;
system ("echo \""Str_Data" "Username" "Proc_Name" "TTY"\" >> '$Log_Path'");
}
}
}';
if [ -e ./auto_killer_data.new ]; then
mv ./auto_killer_data.new ./auto_killer_data
else
echo '' > ./auto_killer_data
fi
#We wait fo a while and repeate process
sleep $Check_Repeating_Time\s;
done;
答案4
我之前遇到过类似的问题,这里有一小段 python 代码来解决这个问题: