用于测试内存使用情况的脚本

用于测试内存使用情况的脚本

在寻找应用程序内存泄漏的解决方案时,我正在尝试贴上临时创可贴。我写的是一个小bash脚本,放在服务器的根目录中。这就是脚本应该做的事情:

  1. 获取它运行的位置
  2. 检查脚本是否是 crontab
  3. 如果 crontab 中没有,请添加到 crontab 以每 5 分钟运行一次
  4. 测试内存并检查%是否高于percent_allowed
  5. 如果以上测试,则重新启动 nginx 和 php-fmp 服务

memory_protect.sh:

#!/bin/sh
cronfile=memory_protect.sh    #NOTE THIS SHOULD DETECT IT'S SELF
path=pwd                      #this is the path to the file 
percent_allowed=80            #this should be max memory before action

has_cron(){
    #is the file in the cron?
    return [[ crontab -l | egrep -v '^$|^#' | grep -q $cronfile ]] && return 1 || return 0
}
test_memory(){
    memusage=`top -n 1 -b | grep "Mem"`
    MAXMEM=`echo $memusage | cut -d" " -f2 | awk '{print substr($0,1,length($0)-1)}'`
    USEDMEM=`echo $memusage | cut -d" " -f4 | awk '{print substr($0,1,length($0)-1)}'`

    USEDMEM1=`expr $USEDMEM \* 100`
    PERCENTAGE=`expr $USEDMEM1 / $MAXMEM`
    #if it's above 80% alert
    return [[ $PERCENTAG>$percent_allowed ]] && return 1 || return 0
}

if [[ has_cron -eq 0 ]]
then
    #was not here so add
    #run this script every 5 mins
    */5 * * * $path/$cronfile
fi

if [[ test_memory ]]
then
    #clear some memory
    /etc/init.d/nginx restart
    /etc/init.d/php-fpm restart
fi

当我自行运行内存测试时,内存测试似乎有效,但这似乎不起作用。


更新 我需要dos2unix在文件上运行,但我也意识到我最终对每个函数的条件都有返回..所以这是行不通的。现在好像说没有找到声明[[if


更新2 看起来很接近,它正在运行服务的重新启动,但它没有将 cron 作业放入..所以我没有看到它正在运行

#!/bin/bash
cronfile=memory_protect.sh    #NOTE THIS SHOULD DETECT IT'S SELF
path=pwd                      #this is the path to the file 
percent_allowed=80            #this should be max memory before action

has_cron(){
    #is the file in the cron?
    #return 0 #returning this just to test should
    #be the next line but it's not working
    return 0
    [[ crontab -l | egrep -v '^$|^#' | grep -q $cronfile ]] && return 1 || return 0
}
test_memory(){
    memusage=`top -n 1 -b | grep "Mem"`
    MAXMEM=`echo $memusage | cut -d" " -f2 | awk '{print substr($0,1,length($0)-1)}'`
    USEDMEM=`echo $memusage | cut -d" " -f4 | awk '{print substr($0,1,length($0)-1)}'`

    USEDMEM1=`expr $USEDMEM \* 100`
    PERCENTAGE=`expr $USEDMEM1 / $MAXMEM`
    #if it's above 80% alert
    [[ $PERCENTAG -gt $percent_allowed ]] && return 1 || return 0
}

if [[ has_cron -eq 0 ]]
then
    #was not here so add
    #run this script every 5 mins
    #crontab -e */5 * * * $path/$cronfile
    cat <(crontab -l) <(echo "*/5 * * * $path/$cronfile") | crontab -
else
    echo "cron present"
fi

if [ test_memory ]
then
    #clear some memory
    sudo /etc/init.d/nginx restart
    sudo /etc/init.d/php-fpm restart
fi

我想现在已经接近被纠正了。

答案1

要通过 Bash 脚本创建 crontab 条目,您需要更改此行:

*/5 * * * * $path/$cronfile

对于这样的事情:

# Write out current crontab
crontab -l > mycron

# Echo new cron into cron file
echo "*/5 * * * * $path/$cronfile" >> mycron

# Install new cron file
crontab mycron
rm mycron

你也可以用这个衬垫来完成这一切:

cat <(crontab -l) <(echo "*/5 * * * $path/$cronfile") | crontab -

你的脚本

这是对我有用的脚本的修改版本。

#!/bin/sh

cronfile=memory_protect.sh    #NOTE THIS SHOULD DETECT IT'S SELF
path=$(pwd)                   #this is the path to the file 
percent_allowed=80            #this should be max memory before action

has_cron(){
    #is the file in the cron?
    #return 0 #returning this just to test should
    #be the next line but it's not working
    if crontab -l | egrep -v '^$|^#' | grep -q $cronfile; then
      return 1
    else
      return 0
    fi
}
test_memory(){
    memusage=$(top -n 1 -b | grep "Mem")
    MAXMEM=$(echo $memusage | cut -d" " -f2 | awk '{print substr($0,1,length($0)-1)}')
    USEDMEM=$(echo $memusage | cut -d" " -f4 | awk '{print substr($0,1,length($0)-1)}')

    USEDMEM1=$(expr $USEDMEM \* 100)
    PERCENTAGE=$(expr $USEDMEM1 / $MAXMEM)
    #if it's above 80% alert
    [[ $PERCENTAG>$percent_allowed ]] && return 1 || return 0
}

if has_cron;
then
    #was not here so add
    #run this script every 5 mins
    #crontab -e */5 * * * $path/$cronfile
    #cat <(crontab -l) <(echo "*/5 * * * $path/$cronfile") | crontab -
    crontab -l > mycron

    # Echo new cron into cron file
    echo "*/5 * * * * $path/$cronfile" >> mycron

    # Install new cron file
    crontab mycron
    rm mycron
else
    echo "cron present"
fi

if test_memory;
then
    #clear some memory
    echo "/etc/init.d/nginx restart"
    echo "/etc/init.d/php-fpm restart"
fi

例子

$ ./memory_protect.sh 
/etc/init.d/nginx restart
/etc/init.d/php-fpm restart

$ crontab -l
*/5 * * * * /home/saml/tst/91789/memory_protect.sh

该脚本需要修改这两行,以便它实际上重新启动nginxphp-fpm服务。

更改这些行: echo "/etc/init.d/nginx restart" echo "/etc/init.d/php-fpm restart"

对于这些:

    /etc/init.d/nginx restart
    /etc/init.d/php-fpm restart

我这样做只是为了看到脚本运行正确。注意:sudo如果此脚本以 root 以外的任何人身份运行,则这些重新启动行应以前缀!

        sudo /etc/init.d/nginx restart sudo /etc/init.d/php-fpm restart

此用途可能需要NOPASSWD至少拥有这两个脚本的权限,否则它将等待拥有 cron 的用户提供密码。

crontab 条目不存在?

当您的 crontab 尚未在目录 中创建时,您将遇到此问题/var/sppol/cron。当你crontab -l像这样运行时你会遇到它:

$ crontab -l
no crontab for saml

再检查一遍:

$ sudo ls -l /var/spool/cron/
total 0
-rw------- 1 root root 0 Sep 16 23:47 root

因此,只需简单地假设您要编辑它,然后保存空文件即可创建它:

$ crontab -e

# now you're in the vim editor, add a empty line
# type "i", hit return, hit Escape,
# and do a Shift + Z + Z to save!

现在你应该看到这个:

$ crontab -l
$ 

和这个:

$ sudo ls -l /var/spool/cron/
total 0
-rw------- 1 root root 0 Sep 16 23:47 root
-rw------- 1 saml root 0 Sep 21 16:20 saml

重新启动服务

您将遇到的另一个问题是,如果此 crontab 条目以用户 user1 身份运行,则 user1 将需要sudo重新启动它们的权限。

答案2

我会用监控为了这

这是 monit 脚本示例,满足您的要求

check process nginx with pidfile /var/run/nginx.pid
  start program = "/etc/init.d/nginx start"
  stop program  = "/etc/init.d/nginx stop"
  if memory usage > 95% then restart
  group www-data 
  if 5 restarts within 5 cycles then timeout 

尝试重启5次;如果 monit 无法重新启动网络服务器 5 次;只是超时以避免竞争状况。

参考链接

相关内容