Redis事件监听

2020-09-26  本文已影响0人  爱折腾的傻小子
关于Docker Laradock Redis配置
FROM redis:latest

LABEL maintainer="Mahmoud Zalt <mahmoud@zalt.me>"

## For security settings uncomment, make the dir, copy conf, and also start with the conf, to use it
RUN mkdir -p /usr/local/etc/redis
COPY redis.conf /usr/local/etc/redis/redis.conf

VOLUME /data

EXPOSE 6379

CMD ["redis-server", "/usr/local/etc/redis/redis.conf"]
#CMD ["redis-server"]
1. 注释 bind 127.0.0.1
2. protected-mode 为 no
## redis3.2版本后新增protected-mode配置,默认是yes,即开启。设置外部网络连接redis服务,设置方式如下:
1、关闭protected-mode模式(no),此时外部网络可以直接访问
2、开启protected-mode保护模式(yes),需配置bind ip或者设置访问密码
docker-compose stop redis
docker-compose build --no-cache redis
docker-compose up -d redis
Laravel/Lumen Redis监听
<?php

namespace App\Console\Commands\RedisSubscribe;

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

class EventListenCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'redis:expired-listen';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'redis expired event listen';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /*
     * redis2.8.0之后提供 事件
     * 配置项如下:
     *  K           键空间通知,所有通知以 keyspace@ 为前缀,针对Key
     *  E           键事件通知,所有通知以 keyevent@ 为前缀,针对event
     *  g           DEL 、 EXPIRE 、 RENAME 等类型无关的通用命令的通知
     *  $           字符串命令的通知
     *  l           列表命令的通知
     *  s           集合命令的通知
     *  h           哈希命令的通知
     *  z           有序集合命令的通知
     *  x           过期事件:每当有过期键被删除时发送
     *  e           驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送
     *  A           参数 g$lshzxe 的别名,相当于是All
     *
     *  这里修改:notify-keyspace-events "Ex"
     *
     *  laravel配置文件config.database.redis.default添加 'read_write_timeout' => -1
     */

    /*
     * 键值类型:
     *      ORDER_CONFIRM_WAIT_PAY:order_sn                 待支付订单30分钟
     */

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        ini_set('default_socket_timeout', -1);
        $cachedb = config('database.redis.expired.database', 9);
        $pattern = '__keyevent@' . $cachedb . '__:expired';     // 过期事件
        Redis::connection('expired')->subscribe([$pattern], function ($channel) {
            $this->info($channel);
            $key_type = Str::before($channel,':');      // 缓存KEY值
            $params = Str::after($channel,':');         // 参数
            Log::channel('expired')->debug("{$key_type}:", ['params'  => $params]);
            switch ($key_type){
                default:
                    break;
            }
        });
    }
}
\Illuminate\Support\Facades\Redis::connection('expired')->setex('ORDER_CONFIRM_WAIT_PAY:1221211221', 10, 123);
Redis 事件
    /*
     * redis2.8.0之后提供 事件
     * 配置项如下:
     *  * K           键空间通知,所有通知以 __keyspace@<db>__ 为前缀,针对Key
     *  * E           键事件通知,所有通知以 __keyevent@<db>__ 为前缀,针对event
     *  * g           DEL 、 EXPIRE 、 RENAME 等类型无关的通用命令的通知
     *  * $           字符串命令的通知
     *  * l            列表命令的通知
     *  * s           集合命令的通知
     *  * h           哈希命令的通知
     *  * z           有序集合命令的通知
     *  * x           过期事件:每当有过期键被删除时发送
     *  * e           驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送
     *  * A           参数 g $ l s h z x e 的别名,相当于是All
     *
     *  这里修改:notify-keyspace-events Ex 表示对过期事件进行通知发送
     *           notify-keyspace-events Kx 表示想监控某个 key 的失效事件
     *           notify-keyspace-events AKE 表示发送所有类型的通知
     */
事件的类型
    /*
     * http://redisdoc.com/key/del.html#del、http://redisdoc.com/pub_sub/publish.html#publish
     * 对于每个修改数据库的操作,键空间通知都会发送两种不同类型的事件:键空间通知(key-space)和键事件通知(key-event)。
     * * 当 del mykey 命令执行时:
     * * *   键空间频道的订阅者将接收到被执行的事件的名字,在这个例子中,就是 del
     * * *   键事件频道的订阅者将接收到被执行事件的键的名字,在这个例子中,就是 mykey
     * * *   比如说,对 0 号数据库的键 mykey 执行del命令时, 系统将分发两条消息, 相当于执行以下两个 publish命令:
     * * *   PUBLISH __keyspace@0__:sampleKey del
     * * *   PUBLISH __keyevent@0__:del sampleKey
     * * *   订阅第一个频道 __keyspace@0__:mykey 可以接收 0 号数据库中所有修改键 mykey 的事件
     * * *   订阅第二个频道 __keyevent@0__:del 则可以接收 0 号数据库中所有执行 del 命令的键
     *
     * 事件是用  __keyspace@DB__:KeyPattern 或者  __keyevent@DB__:OpsType 的格式来发布消息的
     * *   DB表示在第几个库;
     * *   KeyPattern则是表示需要监控的键模式(可以用通配符);
     * *   OpsType则表示操作类型。因此,如果想要订阅特殊的Key上的事件,应该是订阅keyspace。
     */
Redis事件通知
Keyspace 通知使得客户端可以通过订阅频道或模式,来接收那些以某种方式改动了 Redis 数据集的事件(触发某些事件后可以向指定的频道发送通知),
该功能需要 Redis 版本大于 2.8。

事件通过 Redis 的订阅与发布功能(pub/sub)来进行分发,因此所有支持订阅与发布功能的客户端都可以在无须做任何修改的情况下,直接使用此功能。

因为 Redis 目前的订阅与发布功能采取的是发送即忘(fire and forget)策略,所以如果你的程序需要可靠事件通知(reliable notification of 
events),那么目前的键空间通知可能并不适合你:当订阅事件的客户端断线时,它会丢失所有在断线期间分发给它的事件。
Redis过期通知的发送时间
    /*
     * Redis 使用以下两种方式删除过期的键:
     * *   当一个键被访问时,程序会对这个键进行检查,如果键已经过期,那么该键将被删除
     * *   底层系统会在后台渐进地查找并删除那些过期的键,从而处理那些已经过期、但是不会被访问到的键
     * 当过期键被以上两个程序的任意一个发现、 并且将键从数据库中删除时, Redis 会产生一个 expired 通知
     * Redis 并不保证生存时间(TTL)变为 0 的键会立即被删除: 如果程序没有访问这个过期键, 或者带有生存时间的键非常多的话, 那么在键的生存时间变为 0 , 直到键真正被删除这中间, 可能会有一段比较显著的时间间隔
     * 因此, Redis 产生 expired 通知的时间为过期键被删除的时候, 而不是键的生存时间变为 0 的时候
     */

Redis发布/订阅

参考链接:

https://www.cnblogs.com/tangxuliang/p/10659439.html @author Azure沫
https://www.cnblogs.com/yeyusheng/p/8533362.html @author 不干平凡,叶育生

上一篇 下一篇

猜你喜欢

热点阅读