本文目录导读:

- 方式一:文件/日志变化监控(非实时,最基础)
- 方式二:使用 inotify(Linux 原生文件监控)
- 方式三:WebSocket 实时推送(推荐用于 Web 应用)
- 方式四:Server-Sent Events (SSE) —— 单向实时推送
- 方式五:使用现代工具配合(生产推荐)
- 各方法对比
在 PHP 中实现“实时监控”通常有两种理解:一种是轮询(定期请求)来模拟实时,另一种是通过长连接技术(如 WebSocket)实现真正的实时推送。
PHP 本身是请求-响应模式的脚本语言,并不原生支持常驻内存或长连接,但可以通过以下 3 种主要方式实现:
文件/日志变化监控(非实时,最基础)
适用于监控日志文件、目录变化等。
<?php
$file = '/var/log/nginx/access.log';
$lastSize = filesize($file);
while (true) {
clearstatcache();
$currentSize = filesize($file);
if ($currentSize > $lastSize) {
$handle = fopen($file, 'r');
fseek($handle, $lastSize);
$newData = fread($handle, $currentSize - $lastSize);
echo "New log: " . $newData;
$lastSize = $currentSize;
}
sleep(1); // 轮询间隔
}
特点:
- 简单,但会消耗服务器资源
- 不是真正的“实时”,取决于轮询间隔
使用 inotify(Linux 原生文件监控)
PHP 扩展 inotify 可以监控文件/目录的增删改事件,真正的事件驱动,不用轮询。
安装:
pecl install inotify
示例代码:
<?php
$fd = inotify_init();
$watch_descriptor = inotify_add_watch($fd, '/path/to/dir', IN_CREATE | IN_MODIFY);
while (true) {
$events = inotify_read($fd); // 阻塞等待事件
foreach ($events as $event) {
echo "File: " . $event['name'] . " - Event: " . $event['mask'] . PHP_EOL;
// 处理事件...
}
}
inotify_rm_watch($fd, $watch_descriptor);
fclose($fd);
适用场景:
- 监控配置文件变更(自动重载)
- 监控文件上传目录
- 日志实时分析
⚠️ 注意: 需要 PHP CLI 运行,且 inotify 是阻塞的,不能用于 Web 请求。
WebSocket 实时推送(推荐用于 Web 应用)
此方案才是真正的浏览器实时更新,实时数据看板、聊天、推送通知。
安装 Ratchet(PHP WebSocket 库)
composer require cboden/ratchet
服务端代码(WebSocket Server)
<?php
// server.php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
require __DIR__ . '/vendor/autoload.php';
class MonitorServer implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
$this->clients->attach($conn);
echo "New connection: {$conn->resourceId}\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
// 收到客户端消息,可以处理
foreach ($this->clients as $client) {
if ($from !== $client) {
$client->send($msg); // 广播
}
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "Error: {$e->getMessage()}\n";
$conn->close();
}
}
// 启动 WebSocket 服务
$server = IoServer::factory(
new HttpServer(
new WsServer(
new MonitorServer()
)
),
8080 // WebSocket 端口
);
$server->run();
启动服务
php server.php
客户端(浏览器 JavaScript)
// 建立 WebSocket 连接
const ws = new WebSocket('ws://localhost:8080');
ws.onopen = function() {
console.log('连接成功');
// 可以发送订阅消息
ws.send(JSON.stringify({action: 'subscribe', channel: 'monitor'}));
};
ws.onmessage = function(event) {
const data = JSON.parse(event.data);
// 实时更新页面
document.getElementById('realtime-data').innerText = data.value;
};
从 PHP 业务代码推送数据
如果有其他 PHP 脚本需要向 WebSocket 推送数据,可以使用 ZeroMQ 或 Redis Pub/Sub:
// 从业务控制器推送数据
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->publish('monitor_channel', json_encode(['cpu' => 85, 'memory' => 60]));
然后在 WebSocket 服务端订阅 Redis:
// 在 MonitorServer 中增加 Redis 订阅
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->subscribe(['monitor_channel'], function($redis, $channel, $msg) use ($monitorServer) {
foreach ($monitorServer->clients as $client) {
$client->send($msg);
}
});
Server-Sent Events (SSE) —— 单向实时推送
如果只需要服务器向浏览器推送(不需客户端发消息),SSE 比 WebSocket 更轻量。
PHP 服务端:
<?php
// sse.php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
while (true) {
$data = ['cpu' => rand(0, 100), 'memory' => rand(0, 100)];
echo "data: " . json_encode($data) . "\n\n";
ob_flush();
flush();
sleep(2); // 2秒推送一次
}
浏览器接收:
const evtSource = new EventSource('sse.php');
evtSource.onmessage = function(event) {
const data = JSON.parse(event.data);
document.getElementById('cpu').innerText = data.cpu + '%';
};
适用场景:
- 实时看板、监控仪表盘
- 通知提醒
- 不需要双向通信的场景
使用现代工具配合(生产推荐)
PHP 不适合长时间运行的任务,生产环境建议:
| 场景 | 推荐方案 |
|---|---|
| 实时数据看板 | SSE + 后端用 Go/Node.js 推数据 |
| 日志监控 | ELK Stack(Elasticsearch, Logstash, Kibana) |
| 系统指标监控 | Prometheus + Grafana |
| 文件变化监控 | inotify + 将事件写入 Redis/Queue |
| 高并发推送 | Node.js + Socket.IO 或 Go + gorilla/websocket |
各方法对比
| 方式 | 实时性 | 实现难度 | 适用场景 | 备注 |
|---|---|---|---|---|
| 轮询 | 中 | 低 | 简单监控 | 资源浪费 |
| inotify | 高 | 中 | 本地文件监控 | Linux 专用 |
| WebSocket | 最高 | 高 | 双向通信、聊天、推送 | 需要常驻服务 |
| SSE | 高 | 中 | 服务器→浏览器推送 | 单向,简单 |
| 外部工具 | 高 | 低 | 生产环境 | 推荐用于大规模 |
如果你的需求是“监控 PHP 进程/代码变化”,推荐配合 Supervisor + inotify 或使用 Laravel Horizon 等专业工具。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播