redis发布订阅功能

2019-03-27  本文已影响0人  Sunlightotaku

                                                            

一.背景

     目前做了一个功能,需要抓取到登陆时session自动失效的时间,于是在同事的建议下第一次去使用redis的发布订阅功能,这其中踩了些坑,还是耗费了几天时间才做出来了。

     发布订阅功能要求reids最少要是2.8版本以上,大概功能就是发布者发布消息,订阅者接收到发布者发布的消息,具体概念功能,网上可以看哈,这里不多赘述。

二.本地环境

 1.部署环境:docker集成的ngnix,mysql,php,redis 环境   

 2.编程语言:php 

 3.框架:TP5  

 4.数据库:mysql,redis

三.步骤

   1.订阅redis的过期失效事件,只要redis中有键过期则通知订阅的客户端,有两种方式配置:

      第一种是文件配置:修改reids配置文件(redis.conf)【window系统配置文件为:redis.windows.conf 】,更改 notify-keyspace-events "" 为 notify-keyspace-events "Ex",然后重启redis服务。

      第二种是命令行配置: config set notify-keyspace-events KEA

     坑一:在windosw上用文件配置发现不能生效,只有命令行配置生效了,这个在本人电脑上出现了这个情况

  2.自定义失效的键/自定义发布

     代码:

      $redis->setex($key,3,'redis延迟任务');  //$key 3秒钟失效,失效时通知订阅方,自动发布

    如果有需要自己发布的需求,不需要失效的,如下:

       $res=$redis->publish('test','hello,world'.rand(00000,99999));    // test为发布的频道名称,hello,world为发布的消息

 这里我的需求是session失效,session用的是在tp中配置,tp框架可将session写在redis中而不是文件的形式,而且可配置有效时间,所以我不需   要配置上述命令,tp框架已经帮我搞定了。

3.订阅者逻辑处理

  代码:

 //$msg为失效键的键名

 function keyCallback($redis, $pattern, $channel, $msg)

 {

    //回调函数里就是失效时,通知的地方,这里写redis键失效后的处理,$msg为失效键的键名

 }

 上述代码是原生php代码中的逻辑,这里讲下我在tp中的处理,因为TP是对定时任务做了封装,可以自定义命令行,不过多赘述, https://www.kancloud.cn/manual/thinkphp5/235129,如果没用过的同学可以看哈

 tp5框架中的代码

 <?php 

 namespace app\home\command;use think\console\Command;

 use think\console\Input;use think\console\Output;

 class Testextends Command

 {

 protected functioncon figure()

 {

 $this->setName('test')->setDescription('Here is the remark ');

 }

 protected function execute(Input $input,Output $output)

 {

 `````

 //订阅者的回调函数

 $s->psubscribe(array('__keyevent@0__:expired'), function ($redis, $pattern, $channel , $msg){

 //回调函数里就是失效时,通知的地方,这里写redis键失效后的处理,$msg为失效键的键名

 ```````

 }

 }

 }

坑二:订阅的回调函数里,对redis的任何操作都将无效,任何的增删改查都无法用,官方语言:消息订阅者,即subscribe客户端,需要独占链接,即进行subscribe期间,redis-client无法穿插其他操作,此时client以阻塞的方式等待“publish端”的消息;这一点很好理解,因此subscribe端需要使用单独的链接,甚至需要在额外的线程中使用。

4.订阅过后,因为我们需要时刻知道是否有失效事件的产生,所以这个时候我们需要在服务器上一直挂起这个任务

我在这里用的是nohup,关于这个linux命令我介绍几个主要的:

 第一步,不是命令,是在你要执行的脚本文件第一行的位置上声明php编译器的路径

     #! /usr/bin/env php

   注:这里我踩了一坑,我照这样配置发现不生效,我用的是ngnix环境,后面问同事,发现ngnix并不会像apache有php.exe文件,ngnix上是php环境目录,因此,我的声明最后改成了如下

  #! /usr/bin/env/php

第二步,才是在服务器配置

  a. 配置需要后台挂起执行的命令: 

        nohup 命令 &

    注:这里也是我踩的一坑,网上给出的都是 nobup 文件 &,但是我们是用框架,而不是原生php,再加上本地是在docker中搭建的环境,我这里最终的配置是:

       nohup docker exec php-fpm容器名 php编译器位置 tp框架think目录 任务命令名 &

 b.查看后台运行的进程:

      这里遇到了一个小坑,网上很多资料说的是用 jobs -l,但是有个弊端,这个命令只对当前终端生效的,关闭终端后,在另一个终端jobs已经无法看到后台跑得程序了,其实进程已经有了,因为jobs命令是列出的当前shell环境已启动的作业状态,所以一旦关闭终端就没得了,推荐用 ps aux 来查看进程,这个最准确的去判断当前系统的所有进程

 c.终止后台运行的进程:

    kill -9 进程号


欢迎评论,建议,O(∩_∩)O哈哈~

上一篇 下一篇

猜你喜欢

热点阅读