欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于swoole实现vmstat信息曲线展示

程序员文章站 2022-05-18 15:56:45
...

是的,时隔多年我找回了csdn的密码

回顾上一篇博客还是2014年,怀念那时青涩的自己 :)
这么多年过去了,我也依旧没有成为一个牛b的大神。。我恨啊,不过有了swoole就不怕了!

不扯了,这里推荐下我的个人博客: opso’s blog

基于swoole_websocket_server

算是一个swoole练手的项目
https://github.com/opso-code/swoole-vmstat.git

基于Swoole的swoole_websocket_server实现的实时vmstat数据展示服务

  • 基于 swoole_websocket_server 实现websocket实时推送给客户端
  • 使用processexec方法,运行vmstat命令,再将结果广播到websocket
  • 同时具有http服务器功能,浏览器直接访问 http://192.168.33.10:9100 将展示public/index.html
  • 进程命名格式 swoole-vmstat master/manager/worker/task-PID-[编号]

浏览器截图:
基于swoole实现vmstat信息曲线展示

进程名:
基于swoole实现vmstat信息曲线展示

注释我也写得很清楚了,下面是/server.php 主要代码:

<?php

/**
 * 定时执行vmstat,将结果用websocket推送给客户端
 * 进程命名规律:服务名称-master/worker/task-PID-编号
 */

class StatServer
{
    /**
     * @var swoole_websocket_server
     */
    private $server;
    private $onEvents;
    private $server_name;
    /**
     * @var swoole_process
     */
    private $process;

    public function __construct() {
        $this->server_name = 'swoole-vmstat';
        $this->onEvents = array('start', 'workerstart', 'managerstart', 'managerstop','message', 'open', 'close', 'request', 'shutdown', 'task', 'finish');
        $this->init();
    }

    public function init() {
        $this->server = new swoole_websocket_server(WS_HOST, WS_PORT);
        $this->server->set([
            'worker_num' => 1,
            'heartbeat_idle_time' => 30,       // 超过闲置时间关闭
            'heartbeat_check_interval' => 10,   // 每隔多长时间遍历一次客户端fd
            'enable_static_handler' => true,
            'document_root' => PUBLIC_PATH,     // 设置后,所有静态资源都会访问public文件夹
            ''
        ]);
        foreach ($this->onEvents as $event) {
            $fun = 'on' . ucfirst(strtolower($event));
            if (method_exists($this, $fun)) {
                $this->server->on($event, array($this, $fun));
            }
        }

        // 由manager管理进程,执行完命令会被再次拉起
        $this->process = new swoole_process(function (swoole_process $child_process) {
            $name = "{$this->server_name} process-{$child_process->pid}";
//            cli_set_process_title($name);
            $this->putLog("{$name} start");
            sleep(1); // 保证线程被重新拉起的时候隔一秒
            // vmstat 间隔秒 重复次数
            $child_process->exec('/usr/bin/vmstat', array(1, 3600));
        }, true);

        swoole_process::wait(false);

        // process 加入Master管理
        $this->server->addProcess($this->process);
    }

    /**
     * 启动总进程
     */
    public function run() {
        $this->server->start();
    }

    /**
     * 子进程启动
     * @param swoole_websocket_server $serv
     * @param $worker_id
     */
    public function onWorkerStart(swoole_websocket_server $serv, $worker_id) {
        $type = 'worker';
        if ($serv->taskworker) {
            $type = 'task';
        }
        $name = "{$this->server_name} {$type}-{$serv->worker_pid}-{$worker_id}";
        cli_set_process_title($name);
        $this->putLog("{$name} start");

        if ($worker_id == 0) {
            $process = $this->process;
            // 读数据
            swoole_event_add($process->pipe, function ($pipe) use ($process, $serv) {
                $data = trim($process->read());
                $explodeArr = explode(PHP_EOL, $data);
                $info = preg_split('/ +/', trim(end($explodeArr)));
                if (!is_numeric($info[0])) {
                    return;
                }
                $line = implode(',', $info);
//                $this->putLog($line);
                unset($info, $explodeArr, $data);
                // 维持的连接列表
                $conn_list = $serv->connection_list();
                if (empty($conn_list)) {
                    return;
                }
                foreach ($conn_list as $fd) {
                    $conn_info = $serv->connection_info($fd);
                    // 排除非websocket连接
                    if (isset($conn_info['websocket_status']) && $conn_info['websocket_status'] > 0) {
                        $serv->push($fd, $line);
                    }
                }
            });
        }
    }

}

有问题可以一起讨论哦,或者大神们还有什么练手的例子推荐吗?

相关标签: swoole php