redis发布订阅c接口_redis发布订阅功能

一.背景

目前做了一个功能,需要抓取到登陆时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框架中的代码

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哈哈~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django 可以通过使用 Redis发布订阅模型来实现实时通信。下面是使用 Django 和 Redis 实现发布订阅的一般步骤: 1. 安装 Redis 相关库 可以使用 pip 安装 Redis 相关库,例如:redis、django-redis。 2. 配置 Redis 在 Django 的 settings.py 文件中,配置 Redis 的连接信息,例如: ```python CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis://127.0.0.1:6379/0', 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', } } } ``` 3. 发布消息 在 Django 的视图函数中,可以使用 Django-Redis 库的 publish() 函数来发布消息,例如: ```python from django_redis import get_redis_connection redis_conn = get_redis_connection() redis_conn.publish('channel_name', 'message_content') ``` 4. 订阅消息 在 Django 的视图函数中,可以使用 Django-Redis 库的 subscribe() 函数来订阅消息,例如: ```python from django_redis import get_redis_connection from django.http import HttpResponse import redis def stream(request): r = redis.Redis() p = r.pubsub() p.subscribe('channel_name') for message in p.listen(): if message['type'] == 'message': return HttpResponse(message['data']) ``` 上面的代码中,我们使用 Redis 的 pubsub() 函数来订阅 'channel_name' 频道,然后通过 listen() 方法来接收消息。如果收到了消息,就将消息内容返回给客户端。 以上就是使用 Django 和 Redis 实现发布订阅的一般步骤,你可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值