Redis设计主要是用来做缓存的,但是由于它自身的某种特性使得它可以用来做消息队列。

它有几个阻塞式的API可以使用,正是这些阻塞式的API让其有能力做消息队列;

另外,做消息队列的其他特性例如FIFO(先入先出)也很容易实现,只需要一个list对象从头取数据,从尾部塞数据即可;

Redis能做消息队列还得益于其list对象blpop brpop接口以及Pub/Sub(发布/订阅)的某些接口,它们都是阻塞版的,所以可以用来做消息队列。(List : lpush / rpop)

方式一:生产者与消费者模式
使用list结构作为队列,rpush生产消息,lpop消费消息,当lpop没有消息的时候,要适当sleep一会再重试。

或者,不用sleep,直接用blpop指令,在没有消息的时候,它会阻塞住直到消息到来。

具体文章可查看:PHP与redis队列实现电商订单自动确认收货

方式二:发布订阅者模式
使用pub/sub主题订阅者模式,可以实现1:N的消息队列。

基于事件的系统中,Pub/Sub是目前广泛使用的通信模型,它采用事件作为基本的通信机制,提供大规模系统所要求的松散耦合的交互模式:订阅者(如客户端)以事件订阅的方式表达出它有兴趣接收的一个事件或一类事件;发布者(如服务器)可将订阅者感兴趣的事件随时通知相关订阅者。

消息发布者,即publish客户端,无需独占链接,你可以在publish消息的同时,使用同一个redis-client链接进行其他操作(例如:INCR等)

消息订阅者,即subscribe客户端,需要独占链接,即进行subscribe期间,redis-client无法穿插其他操作,此时client以阻塞的方式等待“publish端”的消息;这一点很好理解,因此subscribe端需要使用单独的链接,甚至需要在额外的线程中使用。

redis做异步队列的缺点

在消费者下线的情况下,生产的消息会丢失。此场景,建议用MQ。

使用MQ可查看:在分布式系统上,你是如何处理数据的一致性的

下面用代码实际实现,用发布订阅者模式,给大家讲解讲解

消息订阅者subscribe.php

<?phpini_set ('default_socket_timeout', -1);  //php配置设置不超时$redis = new Redis();$redis->connect("127.0.0.1",6379);//$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);  //redis方式设置不超时,推荐$redis->subscribe(['chan'],'callback');     //callback为回调函数名称//$redis->subscribe(['chan'],array(new TestCall(),'callback') ); //如果回调函数是类中的方法名,这样写// 回调函数,这里写处理逻辑function callback($instance, $channelName, $message){         echo $channelName, "==>", $message, PHP_EOL;         //$instance,即为上面创建的redis实例对象,在回调函数中,默认的这个参数就是,因此不需专门传参。 这里除了SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE这4条命令之外其它命令都不能使用         //如果要使用redis中的其他命令,这样实现         $newredis = new Redis();        $newredis->connect("127.0.0.1", 6379);        echo $newredis->get('test') . PHP_EOL;        $newredis->close();          //可以根据$channelName, $message,处理不同的业务逻辑          switch($chan) {               case 'chan-1':                  ...                  break;               case 'chan-2':                              ...                   break;           }           switch($message) {               case 'msg1':                  ...                  break;               case 'msg2':                              ...                   break;           }}

subscribe.php中设置不超时

方法1:ini_set('default_socket_timeout', -1);

方法2:$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);

如果不设置不超时,60s后会报一个错误

PHP Fatal error: Uncaught RedisException: read error on connection to 127.0.0.1:6379 in subscribe.php:6

方式一的实现,是通过临时修改ini的配置值,default_socket_timeout默认为60s,default_socket_timeout是socket流的超时参数,即socket流从建立到传输再到关闭整个过程必须要在这个参数设置的时间以内完成,如果不能完成,那么PHP将自动结束这个socket并返回一个警告。

方式二是通过修改redis的配置项,因此仅对redis连接生效,相对于方式1,不会产生意外的对其他方法的影响。

消息发布者publish.php

<?php $redis = new Redis();$redis->connect("127.0.0.1",6379);$redis->publish('chan','this is a message');

批量订阅

redis的psubscribe支持通过模式匹配的方式实现批量订阅,订阅方式

$redis->psubscribe(['my*'],'psubscribe'); //回调函数写函数名
或者
$redis->psubscribe(['my*'],array(new TestCall(),'psubscribe')); //回调函数为类中的方法,类名写你自己定义的类

subscribe.php

<?php //ini_set('default_socket_timeout', -1);  //不超时$redis = new Redis();$redis->connect("127.0.0.1",6379);$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);//匹配方式1:发布可用$redis->publish('mymest','this is a message');//$redis->psubscribe(['my*'],'psubscribe');    //匹配方式2:发布可用$redis->publish('mydest','this is a message');//$redis->psubscribe(['my?est'],'psubscribe');//匹配方式3:发布可用$redis->publish('myaest','this is a message');或$redis->publish('myeest','this is a message');$redis->psubscribe(['my[ae]est'],'psubscribe');function psubscribe($redis, $pattern, $chan, $msg) {      echo "Pattern: $pattern";      echo "Channel: $chan";      echo "Payload: $msg";}

模式匹配规则

支持以下几种,以hello举例:

h?llo subscribes to hello, hallo and hxllo
h*llo subscribes to hllo and heeeello
h[ae]llo subscribes to hello and hallo, but not hillo
特殊字符用转义

pubsub方法介绍

public function pubsub( $keyword, $argument )

pubsub获取pub/sub系统的信息,$keyword可用为"channels", "numsub", 或者"numpat",三种,传入不同的keyword返回的数据不同

* $redis->pubsub('channels'); // All channels 获取所有的频道,返回数组* $redis->pubsub('channels', '*pattern*'); // Just channels matching your pattern,返回符合匹配模式的频道* $redis->pubsub('numsub', array('chan1', 'chan2')); // Get subscriber counts for 'chan1' and 'chan2'    //返回每个订阅频道的数量,返回数组* $redis->pubsub('numpat'); // Get the number of pattern subscribers 获取模式匹配方式的订阅的数量,即$redis->psubscribe(['my[ae]est'],'psubscribe');返回数量为1,$redis->subscribe(['chan'],'callback');    这种方式获取不到,因此返回数量为0

毕竟绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,基本是用哪学哪,对 Redis 缺乏了一个整体认知

那么如何才能正确的掌握Redis呢?

为了帮大家快速建立Redis的体系,分享一套Redis实战教程【Redis6.0全套实战教程】

课程目录

1 redis的五种数据结构讲解

2 string结构与应用场景讲解

3 hash结构与应用场景讲解

4 list结构与应用场景讲解

5 set结构与应用场景讲解

6 实例讲解:集合操作实现微博微信关注模型

7 zset有序集合结构与应用场景

8 一线大厂redis深度学习路线指引

9 互联网公司分布式锁场景实例讲解

10 分布式架构下如何实现redis分布式锁

11 redis主从架构锁失效问题及redlock详解

12 基于redisson框架实现分布式锁

13 redisson分布式锁实战原理讲解

14 双十一大促如何将分布式锁性能提升100倍

15 Redis特性与应用场景解析

16 Redis Db数据结构讲解

17 string数据结构讲解

18 字符串数据结构讲解

19 面试题:如何实现亿级用户日活统计

20 Redis6.0多线程工作模式解析

21 Redis阻塞队列实现原理

22 list数据结构讲解

23 hash数据结构讲解

24 一线大厂Redis面试核心知识点梳理

25 redis集群方案比较-哨兵模式详解

26 redis集群方案比较-高可用集群模式

27 redis安装

28 redis集群搭建过程详解

29 验证集群

30 轻松搭建redis缓存高可用集群

非常抱歉由于头条规则无法发放资料外链,领取方式:点赞关注小编后私信【资料】获取资料领取方式!

部分资料展示:

领取方式:点赞关注小编后私信【资料】获取资料领取方式!

aliyun redis 链接超时_用redis做异步队列,原来还可以这样相关推荐

  1. redis 主从配置_应用 | Redis实现 主从,单例,集群,哨兵,配置应用

    小小经过一天的休整 公众号更新规则:每周六将会停更一次,进行短期的休整,其余时间继续每天一更. 思维导图如下 Redis 主从配置 这里配置Redis主从 什么是主从 主从复制,是指把一台Redis服 ...

  2. redis 统计数量_使用redis实现在线人数统计

    实现方案 用户登录的时候往redis里面存储一个值(对应的在线人数增1),这个值的key值是和这个用户的唯一识别码(例如userId或者username)有联系,在存储的同时,设置其对应的生命周期,比 ...

  3. Redis 链接时好时坏[ error ] [2]Redis::pconnect(): connect() failed: Connection timed out

    发生原因:thinkphp 中的session 存的是redis ,今天的图形验证码也存的redis 刷新多次会出现请求不到的情况,查看php错误日志看到是redis链接失败了,但是不是直接链接不了, ...

  4. redis怎么开启_关于Redis数据库入门必备的学习点

    Redis数据库 1.完全基于内存读写的非关系型数据库(支持持久化存储) [1]key:value键值对方式组织数据,所有的键值对都有设置过期的功能<弱事务型的数据库>: [2]核心操作都 ...

  5. redis使用sysc超时_基于redis的分布式锁实现

    随着业务越来越复杂,应用服务都会朝着分布式.集群方向部署,而分布式CAP原则告诉我们,Consistency(一致性). Availability(可用性).Partition tolerance(分 ...

  6. python3 redis长链接超时_Python3 连接Redis字符串和字节问题探究

    前言 Python3将逐渐代替Python2,Python2和3还是有很多不同.在开发过程中报了错: File "/home/hzw/project/test/virtualenv/lib/ ...

  7. gin redis 链接不上_php + redis 高并发商品秒杀 完整业务模拟流程 实现方案

    关于商品秒杀 之前百度了很多关于商品秒杀的业务怎么做,网上的答案真的是五花八门,归纳一下就两种方式 队列或计数器 网上大部分都没有写具体的代码业务 我这里模拟一个业务小场景进行实践 商品:1 每日限量 ...

  8. java redis id生成器_基于redis的分布式ID生成器

    项目地址 基于redis的分布式ID生成器. 准备 首先,要知道redis的EVAL,EVALSHA命令: 原理 利用redis的lua脚本执行功能,在每个节点上通过lua脚本生成唯一ID. 生成的I ...

  9. java redis 商品秒杀_使用redis秒杀出现产品超发现象求解?

    亲测,用ab 压测并发500 请求4000 无超卖! header("content-type:text/html;charset=utf-8"); $redis = new re ...

最新文章

  1. arm linux arp 支持,当ARP缓存为空 - RL-ARM 实时库用户指南
  2. django性能优化缓存view详解
  3. hack 入侵 142 主机的过程
  4. 《Java 7程序设计入门经典》一1.10 另一种数据类型
  5. super-smack
  6. 向设计师分享30个免费的扁平化风格设计素材
  7. 关系抽取;串联抽取和联合抽取论文总结
  8. 关于Windows 8 用户使用习惯调查结果
  9. atoi atol实现
  10. 计算机显卡内存分布查看,Win10电脑查看显卡内存的详细教程
  11. 5个增加设计趣味性的方法
  12. Unity的Animator的动画层(Layer)
  13. 使用Haskell和Hubris加强Ruby
  14. 学Java 这样入门 28天轻松掌握
  15. 芯片底部焊接不良失效分析
  16. 基于HFSS的天线设计流程
  17. 指纹识别-(10)指纹图像细节点特征提取之FingerNet卷积网络
  18. HEAP: HEAP: Free Heap block xx modified at xxafter it was freed 堆内存出现野指针错误
  19. The Open Group 2018 北京峰会召开,看行业大咖都说了哈?
  20. 用Java实现:设有一根长3000m 的绳子,每天减一半,需要几天的时间,绳子的长度会短于5m?

热门文章

  1. 我发现现在在电视编剧也挺宅的
  2. Openfiler 2.3配置及Win2k8 iSCSI应用系列之二
  3. egg风格 什么意思_egg是什么意思
  4. pd.DataFrame.drop_duplicates
  5. NLP 注意力机制总结言简意赅的
  6. 强强联合!智源x清华AIR,共启 AI 健康研究新篇章
  7. 打开深度学习的黑盒,详解神经网络可解释性
  8. 图灵奖获得者 Alan Kay:突破常规思维,创建下一代科研社区(附视频)
  9. 独家 | 主成分分析用于可视化(附链接)
  10. 【经典书】随机矩阵理论与无线网络