基于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实时推送给客户端 - 使用
process
的exec
方法,运行vmstat
命令,再将结果广播到websocket
- 同时具有
http
服务器功能,浏览器直接访问http://192.168.33.10:9100
将展示public/index.html
- 进程命名格式 swoole-vmstat master/manager/worker/task-PID-[编号]
浏览器截图:
进程名:
注释我也写得很清楚了,下面是/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);
}
}
});
}
}
}
有问题可以一起讨论哦,或者大神们还有什么练手的例子推荐吗?