转至:http://blog.csdn.net/hfahe/article/details/6627033
摘要:如果你的服务器主要服务不定期被kill掉,如何来尽可能保证服务正常?
前几天某台服务器出现了问题,主要的进程(包括Web服务、top、vi这样的命令)都会不定期被kill掉,经过分析认为这台服务器的系统出现了问题,必须要进行重装。而这台服务器上面挂载了很重要的Web服务,要保证服务还能够正常的运行,必须要进行服务的迁移。
但是新服务器到位还需要一定时间,这段时间内我们如何来保证服务的正常性呢?采用人工的方式费时费力,而且0点到8点全时段监控是不太可能的。采用crontab的方式可行,但是问题是crontab最小的运行间隔为1分钟,服务在1分钟内出现问题的几率很大,那么服务最长不可用的时间为1分钟,影响很大。用执行脚本的方式可行,但是也会被kill掉,无法起到一直监控的作用。有什么好的方式呢?
解决问题的思路是我们在其他服务器上监控服务状态(这个很容易实现),并且通过远程执行脚本的方式来进行服务的重启。
1、 监控服务状态
监控服务状态的方式有多种,例如远程获取系统进程列表分析和HTTP请求。我们用最简单的方式:通过HTTP请求的状态判断服务的可用性。
1) 先在被监控的服务器(下文用服务器1代替)上写一个简单的PHP页面,只需要输出固定的内容。
2) 在监控服务器(下文用服务器2代替)上用Perl脚本访问这个Web页面,如果取得的内容和确定的内容不一致,视为服务不可用(也可以使用HTTP状态码判断)。下面是check_down.pl代码:
2、 远程执行重启脚本
检测到服务不可用,下面是最关键的步骤,远程执行重启脚本。
1)下面是服务器1上检测并重启的Shell脚本check_down.sh。
2)我们要在服务器2上调用服务器1上的此脚本,可以采用ssh的方式,但是关键是执行ssh命令时不需要输入密码。
执行ssh命令不需要密码的方式如下:
在服务器2上执行"ssh-keygen-t rsa",一路回车即可。
在服务器1进入/root/.ssh目录,执行“viauthorized_keys”,将服务器2上/root/.ssh/id_rsa.pub文件中的内容追加到此文件中。
可以直接在服务器2上使用“ssh root@服务器1的ip”的方式登陆了,远程执行重启脚本的方式是“ssh root@服务器1的ip '/path/check_down.sh'”。
3) 调整Perl脚本,在服务器down掉的情况下加入远程执行重启脚本的调用。
大功告成!
在服务器2上启动Perl脚本“perl check_down.pl&”,然后就可以在输出的日志文件里看到结果了:
总结:
如上的方案很简单,但是编写了Shell、Perl、PHP脚本,它们各自提供了不同的作用。另外重要的是解决问题的思路,如何在不可能的情况下绕过问题从另外一个方面考虑解决方案。
摘要:如果你的服务器主要服务不定期被kill掉,如何来尽可能保证服务正常?
前几天某台服务器出现了问题,主要的进程(包括Web服务、top、vi这样的命令)都会不定期被kill掉,经过分析认为这台服务器的系统出现了问题,必须要进行重装。而这台服务器上面挂载了很重要的Web服务,要保证服务还能够正常的运行,必须要进行服务的迁移。
但是新服务器到位还需要一定时间,这段时间内我们如何来保证服务的正常性呢?采用人工的方式费时费力,而且0点到8点全时段监控是不太可能的。采用crontab的方式可行,但是问题是crontab最小的运行间隔为1分钟,服务在1分钟内出现问题的几率很大,那么服务最长不可用的时间为1分钟,影响很大。用执行脚本的方式可行,但是也会被kill掉,无法起到一直监控的作用。有什么好的方式呢?
解决问题的思路是我们在其他服务器上监控服务状态(这个很容易实现),并且通过远程执行脚本的方式来进行服务的重启。
1、 监控服务状态
监控服务状态的方式有多种,例如远程获取系统进程列表分析和HTTP请求。我们用最简单的方式:通过HTTP请求的状态判断服务的可用性。
1) 先在被监控的服务器(下文用服务器1代替)上写一个简单的PHP页面,只需要输出固定的内容。
<?php
echo “alive”;
?>
2) 在监控服务器(下文用服务器2代替)上用Perl脚本访问这个Web页面,如果取得的内容和确定的内容不一致,视为服务不可用(也可以使用HTTP状态码判断)。下面是check_down.pl代码:
use LWP::Simple;
use POSIX qw(strftime);
sub convert_format_time {
my $time = shift;
my $utc = strftime( "%z", localtime );
$utc = substr( $utc, 0, -2 );
return strftime( "%Y-%m-%d %H:%M:%S", localtime( ( 8 - $utc )* 60 * 60 + $time ) );
}
while(true) {
open($FH,">>check_result.out") or die "$!";
$result =LWP::Simple::get("http://xxx.xxx.xxx.xxx/check_down.php");
$time = convert_format_time(time);
if($result ne 'alive') { # server error
print $FH "serverdown!-" . $result . "-" . $time . "\n";
}
else { # server alive
print $FH "serveralive.-" . $time . "\n";
}
close($FH);
sleep(1);
}
2、 远程执行重启脚本
检测到服务不可用,下面是最关键的步骤,远程执行重启脚本。
1)下面是服务器1上检测并重启的Shell脚本check_down.sh。
#!/bin/bash
php_procs=`psaux | grep php-fpm | grep -v grep | wc -l`
if [ $php_procs-lt 1 ]
then
/etc/init.d/nginx start
/etc/init.d/php5-fpm start
fi
2)我们要在服务器2上调用服务器1上的此脚本,可以采用ssh的方式,但是关键是执行ssh命令时不需要输入密码。
执行ssh命令不需要密码的方式如下:
在服务器2上执行"ssh-keygen-t rsa",一路回车即可。
在服务器1进入/root/.ssh目录,执行“viauthorized_keys”,将服务器2上/root/.ssh/id_rsa.pub文件中的内容追加到此文件中。
可以直接在服务器2上使用“ssh root@服务器1的ip”的方式登陆了,远程执行重启脚本的方式是“ssh root@服务器1的ip '/path/check_down.sh'”。
3) 调整Perl脚本,在服务器down掉的情况下加入远程执行重启脚本的调用。
if($result ne 'alive') { # server error
$restart_result = `ssh root\@ip'/usr/local/bin/check_down.sh'`;
print $FH "serverdown!-" . $result . "-" . $time . "\n";
print$FH "$restart_result" . "\n";
}
大功告成!
在服务器2上启动Perl脚本“perl check_down.pl&”,然后就可以在输出的日志文件里看到结果了:
server alive.-2011-07-10 21:05:25
server down!--2011-07-22 21:05:26
Starting nginx: nginx.
* Starting PHP5 FPM...
...done.
server alive.-2011-07-10 21:05:29
总结:
如上的方案很简单,但是编写了Shell、Perl、PHP脚本,它们各自提供了不同的作用。另外重要的是解决问题的思路,如何在不可能的情况下绕过问题从另外一个方面考虑解决方案。