You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Laravel应用监控Redis Key变更并在仪表盘展示方案咨询

嘿,针对你这个Laravel仪表盘同步Redis告警设备集合的需求,我整理了几个实用的方案,你可以根据自己的架构和实时性要求来选:

方案一:Redis键空间通知 + Laravel事件/广播(实时同步首选)

这个方案利用Redis原生的键空间通知功能,当device:alarming这个SET有增减操作时,主动触发通知,Laravel监听后同步更新仪表盘,能做到近乎实时的效果。

步骤1:开启Redis键空间通知

首先得让Redis支持键事件通知,修改你的Redis配置文件(redis.conf),找到notify-keyspace-events这一行,改成:

notify-keyspace-events "KEA"
  • K代表监听键空间事件,E代表监听键事件,A代表监听所有类型的事件。如果想更精准,可以改成K$(只监听SET相关操作),不过先开全量更稳妥。

改完后重启Redis服务,或者用命令临时生效(重启后会失效):

redis-cli CONFIG SET notify-keyspace-events "KEA"

步骤2:Laravel里实现Redis订阅监听

创建一个Artisan命令来持续监听Redis的通知频道:

php artisan make:command RedisAlarmingDeviceListener

然后修改命令的逻辑:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;

class RedisAlarmingDeviceListener extends Command
{
    protected $signature = 'redis:listen-alarming-devices';
    protected $description = '监听Redis中device:alarming集合的变更';

    public function handle()
    {
        $redis = Redis::connection();
        // 订阅db0中device:alarming键的所有变更事件(db号根据你的配置调整)
        $channel = '__keyspace@0__:device:alarming';
        
        $this->info('开始监听device:alarming集合的变更...');
        
        $redis->subscribe([$channel], function ($message, $channel) {
            // $message就是触发的Redis命令,比如sadd、srem、del等
            $this->info("收到变更事件: {$message}");
            
            // 触发Laravel事件,交给监听器处理同步逻辑
            event(new \App\Events\AlarmingDevicesUpdated());
        });
    }
}

步骤3:创建事件和监听器

先创建事件:

php artisan make:event AlarmingDevicesUpdated

然后创建处理更新的监听器:

php artisan make:listener UpdateAlarmingDevicesDashboard --event=AlarmingDevicesUpdated

修改监听器的handle方法,同步缓存并推送前端更新:

<?php

namespace App\Listeners;

use App\Events\AlarmingDevicesUpdated;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Cache;

class UpdateAlarmingDevicesDashboard implements ShouldQueue
{
    // 标记为队列任务,避免阻塞Redis订阅进程
    use \Illuminate\Queue\InteractsWithQueue;

    public function handle(AlarmingDevicesUpdated $event)
    {
        // 获取最新的告警设备ID列表
        $alarmingDevices = Redis::smembers('device:alarming');
        
        // 缓存最新数据,仪表盘直接读缓存减少Redis请求
        Cache::put('alarming_devices', $alarmingDevices, now()->addMinutes(5));
        
        // 推送实时更新到前端(需要Laravel Echo配合)
        broadcast(new \App\Events\AlarmingDevicesBroadcast($alarmingDevices));
    }
}

别忘了在app/Providers/EventServiceProvider.php里注册事件和监听器:

protected $listen = [
    \App\Events\AlarmingDevicesUpdated::class => [
        \App\Listeners\UpdateAlarmingDevicesDashboard::class,
    ],
];

步骤4:前端实时更新(可选)

如果要让仪表盘自动刷新,用Laravel Echo配合广播事件。先创建广播事件:

php artisan make:event AlarmingDevicesBroadcast

修改广播事件:

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class AlarmingDevicesBroadcast implements ShouldBroadcast
{
    use Dispatchable, SerializesModels;

    public $alarmingDevices;

    public function __construct($alarmingDevices)
    {
        $this->alarmingDevices = $alarmingDevices;
    }

    public function broadcastOn()
    {
        // 用公开频道,不需要认证
        return new Channel('alarming-devices');
    }
}

前端用Echo监听并更新DOM:

// 初始化Echo后监听频道
Echo.channel('alarming-devices')
    .listen('AlarmingDevicesBroadcast', (event) => {
        updateAlarmingDevicesList(event.alarmingDevices);
    });

function updateAlarmingDevicesList(devices) {
    const list = document.getElementById('alarming-devices-list');
    list.innerHTML = '';
    devices.forEach(deviceId => {
        const item = document.createElement('li');
        item.textContent = `告警设备ID: ${deviceId}`;
        list.appendChild(item);
    });
}

步骤5:守护监听进程

这个Artisan命令需要持续运行,用Supervisor或者Systemd来守护,比如Supervisor配置:

[program:laravel-redis-alarm-listener]
process_name=%(program_name)s
command=php /path/to/your/project/artisan redis:listen-alarming-devices
autostart=true
autorestart=true
user=www-data
stdout_logfile=/path/to/your/project/storage/logs/redis-listener.log
stderr_logfile=/path/to/your/project/storage/logs/redis-listener-error.log

方案二:定时轮询Redis(简单易实现,适合低频率变更场景)

如果你的Redis环境不能修改配置,或者对实时性要求不高,定时轮询是个省心的选择。

步骤1:创建轮询任务

php artisan make:job CheckAlarmingDevicesChanges

修改任务逻辑:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Cache;

class CheckAlarmingDevicesChanges implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function handle()
    {
        $currentDevices = Redis::smembers('device:alarming');
        $cachedDevices = Cache::get('alarming_devices', []);
        
        // 对比当前数据和缓存数据,有变化才更新
        if ($currentDevices !== $cachedDevices) {
            Cache::put('alarming_devices', $currentDevices, now()->addMinutes(5));
            broadcast(new \App\Events\AlarmingDevicesBroadcast($currentDevices));
        }
    }
}

步骤2:注册调度任务

在app/Console/Kernel.php里添加定时任务:

protected function schedule(Schedule $schedule)
{
    // 每10秒轮询一次,可根据需求调整频率
    $schedule->job(new \App\Jobs\CheckAlarmingDevicesChanges())->everyTenSeconds();
}

记得开启Laravel的调度器(用Cron或者Supervisor):

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

注意事项

  • 性能考量:如果device:alarming变更非常频繁,建议把事件处理放到队列里(监听器实现ShouldQueue),避免阻塞Redis订阅进程。
  • Redis权限:确保Laravel应用的用户有Redis的订阅权限,以及进程运行用户有权限读写项目文件。
  • 缓存策略:仪表盘优先读缓存,避免每次请求都直接查Redis,提升响应速度。

内容的提问来源于stack exchange,提问作者Adnan Shahriar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:53:55