猿问

我准备用redis的list做一个队列系统,基本思路是:

1.把信息用LPUSH操作加到redis中某个list的头部

2.写个cron定时执行php读取这个list。使用redis的RPOP操作从list尾部取走信息

此外,redis有个BRPOP的操作,当list里没有未处理信息时,会把脚本阻塞住,有新的信息时才会继续执行。

请问php怎么利用这个特性,要注意什么,另外这种长时间的连接对性能有没有什么影响?
ps.这样的队列系统设计合理吗?


万千封印
浏览 93回答 2
2回答

侃侃无极

首先你在shell下执行php,完全没有最长实行时间这一说,你完全可以把一个php脚本作为进程不停的监听。但是,你用LIST做队列系统完全没必要,一个是BRPOP的block是有最长时间限制的,你不能一直hold在那里。而更好的选择是利用redis的PUB/SUB机制来做下面是一个简单监听进程,它监听了channel-1,你在shell下执行它不要关掉<?php$redis->subscribe(array('channel-1'),&nbsp;function&nbsp;($redis,&nbsp;$chan,&nbsp;$msg)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;do&nbsp;something &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;$msg; });然后在其它的程序里向channel-1发送你需要发送的消息<?php$redis->publish('channel-1',&nbsp;'hello,&nbsp;world!');如果你需要用LIST来操作,完全可以不要用BRPOP,直接在循环中RPOP就行<?phpwhile&nbsp;(true)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;$msg&nbsp;=&nbsp;$redis->rPop('list-1');&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(false&nbsp;!==&nbsp;$msg)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;这里处理消息 &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;这里可以sleep &nbsp;&nbsp;&nbsp;&nbsp;sleep(60); }

慕婉清6462132

BRPOPLPUSH source destination timeoutBRPOPLPUSH 是 RPOPLPUSH 的阻塞版本,当给定列表 source 不为空时, BRPOPLPUSH 的表现和 RPOPLPUSH 一样。当列表 source 为空时, BRPOPLPUSH 命令将阻塞连接,直到等待超时,或有另一个客户端对 source 执行 LPUSH 或 RPUSH 命令为止。超时参数 timeout 接受一个以秒为单位的数字作为值。超时参数设为 0 表示阻塞时间可以无限期延长(block indefinitely) 。完全能够用LIST构建一个队列,用BRPOPLPUSH不会有超时问题
随时随地看视频慕课网APP
我要回答