swoole 使用毫秒定时器监控服务,并报警

一、场景介绍

在服务用户比较庞大时,服务挂掉一会都可能会造成莫大损失,因此,我们平时的开发中,对于重要的服务的监控就显得非常重要,这也是维持高可用的比较关键的一点。

比如,我们每隔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所在的绝对路径,第二部分是脚本所在的绝对路径,第三部分是定义如果脚本有输出,输出到哪里