auto restart Apache when high load average

My server always shut down when it reach a high load average. I have optimized my Apache, MySQL. But I cannot prevent sometime in a heavy traffic. So I try to write some shell to control load average.

#!/bin/bash
check=`uptime | sed 's/./ /' | awk '{print $10}'`
if[$check -gt 5]
then
  /usr/bin/systemctl restart httpd.service
fi

but it report error when I excuse the script

/var/www/html/load_average.sh: line 3: if[0.98, -gt 5]: command not found
/var/www/html/load_average.sh: line 4: syntax error near unexpected token `then'
/var/www/html/load_average.sh: line 4: `then'

Another question, how to run the script in every 10 seconds with cronjob?

another working code, share to everyone:

#!/bin/bash
check=$(uptime | tr -d ',' | awk '{print $10}')
if [[ $check > 5 ]]; then
  /usr/bin/systemctl restart httpd.service
fi

in cronjob part

* * * * * /var/www/html/load_average.sh >/dev/null 2>&1
* * * * * sleep 10; /var/www/html/load_average.sh >/dev/null 2>&1
* * * * * sleep 20; /var/www/html/load_average.sh >/dev/null 2>&1
* * * * * sleep 30; /var/www/html/load_average.sh >/dev/null 2>&1
* * * * * sleep 40; /var/www/html/load_average.sh >/dev/null 2>&1
* * * * * sleep 50; /var/www/html/load_average.sh >/dev/null 2>&1
Asked By: space and time

||

You must separate the brackets from the data with spaces, like this:

for I in 0 1 2 3 4 5; do
    check=$(uptime | tr -d ',.' | awk '{print $10}')
    if [ "$check" -gt 5 ]; then
        /usr/bin/systemctl restart httpd.service
    fi
    sleep 10
done

In UNIX, [ is really a shell command. When the shell replaces the $check variable by its value, it will try to find the resulted command, hence the error. Additionally, I suggest you quoting the $check variable, as if it gets replaced by an empty string or a whitespace, it would by a syntax error.

Regarding your crontab question, execute crontab -e and add an entry like this one to your file:

* * * * * /PATH/TO/YOUR/SCRIPT

Cronjobs minimal resolution elapse time is 1 minute, so, you will have to use a loop for repeting the check 6 times every ten seconds.

Answered By: Antxon

if[0.98, -gt 5]

Bash can’t do floating point arithmetic. You can do if (( 98 > 500 )) – double round parens allow arithmetic expressions and variable expanding is done in such automatically, so if (( check > 500 )) if your variable is $check. Fortunately, awk does handle basic arithmetic pretty well.

#!/bin/bash
check=$(LC_ALL=C uptime | awk '{print 100*$10 }')
if (( check > 5 ))
then
  /usr/bin/systemctl restart httpd.service
fi

Backticks are deprecated for ages, now.

However, restarting the web server, when too busy might annoy enough visitors, to push the load average down. It doesn’t lock as the right solution since it increases the work. Maybe a profiler might help in finding a bottleneck.

And probably better ways to limit the load average, the web server may cause, exist from within the project – I could only give advice how to improve the shell script.

The LC_ALL setting is probably only needed on my machine, which uses a German environment by default and shows 0.83 as 0,83. But it will not be wrong either.

Answered By: user unknown
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.