redis之键事件(过期)通知实现定时邮件发送

主体思路:
使用redis 键在多长时间后过期,(在过期时间点)通知订阅消费端执行定时邮件发送并更新发送结果。
redis的键过期事件也是一种 发布/订阅模型

  1. 修改redis配置文件,使其支持键事件过期通知
$ vi /usr/local/redis/etc/redis.conf
修改 notify-keyspace-events 的参数为 "Ex", 并重新启动redis
  1. 使用下面代码为订阅端, 检测key过期后的异步通知。
$redis = new Redis();
$redis->connect("127.0.0.1",6379);
$redis->auth("XXX");
$redis->setOption(Redis::OPT_READ_TIMEOUT,-1); // 使其守护进程不会出现超时错误
$redis->psubscribe(["__keyevent@0__:expired"],function(Redis $redis,string $pattern,string $channel,string $expireKey){
    var_dump($pattern); // __keyevent@0__:expired
    var_dump($channel); // __keyevent@0__:expired
    var_dump($expireKey); // 返回 过期的 key,实际业务中,希望每一个定时邮件的key都是唯一的,
//否则正在执行的key业务,如果一个同样的key在执行时过期,则不会执行
    // todo 业务代码继续...
});
  1. 具体实现步骤
3,1 . 发送定时邮件时,将要发送的定时邮件保存到mysql中,并在定时邮件发送表中创建是否已经发送的标识字段 is_send,该字段由redis键空间订阅端执行发送更新。
3,2 . 发送定时邮件时,使用php 操作redis设置一个过期key (重点说明:这个key必须要是唯一的过期key,该业务中过期的key,已经在订阅端执行过的,不能再使用),业务设计中最好带上上一步的mysql主键key 。
$redis->setex(string "delayMail:{$mysqlPriKeyId}",int 定时发送时间-time(),1);
3,3 . 由于在定时邮件未发送之前,用户可能会删除该定时邮件或修改定时邮件发送时间。此时需要调用php的redis删除原来的key,并重新设置key并设置新的过期时间
if($redis->exist("delayMail:{$mysqlPriKeyId}")){
    $redis->del("delayMail:{$mysqlPriKeyId}");
    // 如果用户是 修改定时邮件发送时间,则需要重新设置key
    $redis->setex(string "delayMail:{$mysqlPriKeyId}",int 新的定时发送时间-time(),1);
}

你可能感兴趣的:(redis之键事件(过期)通知实现定时邮件发送)