一、场景介绍
在服务用户比较庞大时,服务挂掉一会都可能会造成莫大损失,因此,我们平时的开发中,对于重要的服务的监控就显得非常重要,这也是维持高可用的比较关键的一点。
比如,我们每隔1秒就去查询 redis 的状态,如果挂掉了,就给管理员发短信和邮件,进行报警,提醒管理员尽快处理。
当然,还可以监控内存、硬盘、接口响应时间等等。
二、环境要求
安装了 PHP 环境
安装了swoole扩展,并且版本号大于 2.2,最好使用最新版本
三、代码实现
ServiceMonitoring.php
<?php
declare(strict_types = 1);
/**
* 服务监控
* 由于Linux 的 crontab 最小粒度为分,因此这里使用 swoole 的毫秒定时器
*
* Class ServiceMonitoring
*/
class ServiceMonitoring
{
/**
* 监控指定端口服务是否正常
*
* @param int $port
*/
public function monitoringPort(int $port)
{
// netstat -anp | grep 8811 | grep LISTEN | wc -l
$shell = 'netstat -anp 2>/dev/null | grep '. $port. '| grep LISTEN | wc -l';
$result = shell_exec($shell);
if ($result != 1) {
// 发送邮件给管理员
// 发送短信服务给管理员
echo date('Y-m-d H:i:s').'---- 端口号为'.$port.'的服务挂掉了-----'.PHP_EOL;
return false;
} else {
echo date('Y-m-d H:i:s').'---- 端口号为'.$port.'正常运行-----'.PHP_EOL;
return true;
}
}
}
// 使用毫秒定时器进行监控,如果检测到服务已经挂掉,则将该服务的监控定时器移除,避免频繁发短信或邮件给管理员,管理员修复好后,重启该脚本
swoole_timer_tick(2000, function ($timerId) {
if (false == (new ServiceMonitoring())->monitoringPort(8811)) {
swoole_timer_clear($timerId);
};
});
swoole_timer_tick(2000, function ($timerId) {
if (false == (new ServiceMonitoring())->monitoringPort(6379)) {
swoole_timer_clear($timerId);
};
});
四、实现效果
注:可以使用 nohup
命令,使得脚本在后台运行
举例:
nohup /usr/local/php/bin/php /data/script/swoole/ServiceMonitoring.php > /logs/script.log
参数解释:总共分为三部分,第一部分是php所在的绝对路径,第二部分是脚本所在的绝对路径,第三部分是定义如果脚本有输出,输出到哪里