Home  >  Article  >  Backend Development  >  redis - php阻塞式连接有没有性能的问题

redis - php阻塞式连接有没有性能的问题

WBOY
WBOYOriginal
2016-06-06 20:51:17913browse

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

1.把信息用LPUSH操作加到redis中某个list的头部
2.写个cron定时执行php读取这个list。使用redis的RPOP操作从list尾部取走信息

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

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

回复内容:

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

1.把信息用LPUSH操作加到redis中某个list的头部
2.写个cron定时执行php读取这个list。使用redis的RPOP操作从list尾部取走信息

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

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

首先你在shell下执行php,完全没有最长实行时间这一说,你完全可以把一个php脚本作为进程不停的监听。

但是,你用LIST做队列系统完全没必要,一个是BRPOP的block是有最长时间限制的,你不能一直hold在那里。而更好的选择是利用redis的PUB/SUB机制来做

下面是一个简单监听进程,它监听了channel-1,你在shell下执行它不要关掉

<?php $redis->subscribe(array('channel-1'), function ($redis, $chan, $msg) {
    // do something
    echo $msg;
});

然后在其它的程序里向channel-1发送你需要发送的消息

<?php $redis->publish('channel-1', 'hello, world!');
更新LIST方法

如果你需要用LIST来操作,完全可以不要用BRPOP,直接在循环中RPOP就行

<?php while (true) {
    $msg = $redis->rPop('list-1');

    if (false !== $msg) {
        // 这里处理消息
    }

    // 这里可以sleep
    sleep(60);
}

BRPOPLPUSH source destination timeout

BRPOPLPUSH 是 RPOPLPUSH 的阻塞版本,当给定列表 source 不为空时, BRPOPLPUSH 的表现和 RPOPLPUSH 一样。

当列表 source 为空时, BRPOPLPUSH 命令将阻塞连接,直到等待超时,或有另一个客户端对 source 执行 LPUSH 或 RPUSH 命令为止。

超时参数 timeout 接受一个以秒为单位的数字作为值。超时参数设为 0 表示阻塞时间可以无限期延长(block indefinitely) 。

完全能够用LIST构建一个队列,用BRPOPLPUSH不会有超时问题

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn