使用PHP+Redis实现任务队列

小天天天天    PHP    999+ 次    2017-03-28 03:22:31


// 创建请求ID标志, uniqid 无法保证唯一, 自己去搜索生成唯一的方法
$uuid = uniqid();
$tsk_name = "mytask";
$time_out = 30000; // 超时策略: 30秒
$time_start = time();
$redis->rPush($tsk_name, $uuid); // 右(后)插入队列

// 堵塞等待队列中第一个和$uuid匹配的(到我了)
while($uuid != $redis->lGet($tsk_name, 0)){
    if((time()-$time_start)> $time_out) {
        break; // 超时跳出(某些原因队列异常了, 可能永远取不到)
    }
    usleep(10); // sleep 10ms, 再次尝试
}

// 这里执行任务的处理代码....

// $response 已拼装好要返回的内容
// 处理完成后(数据库等已入库更新), 需要:
if($redis->lGet($tsk_name, 0) == $uuid){ // 再次确认第一个是本请求
    $redis->lPop($tsk_name); // 完成任务了, 从队列中移除
}else{ 
    // 出现这种情况, 是因为超时了, 或前面的$uuid没有被消费
    // 若不清除, 后续的请求, 都将无法正常进入队列执行
    // 取队列中的所有$uuid
    $queues = $redis->lRange($tsk_name, 0, -1);
    foreach($queues as $i=>$uid){
        if($uid==$uuid){ 
            // 队列中仍存在当前的$uuid
            // 清除$uuid以前异常的队列, 让后边的请求得以正常排队
            $redis->lTrim($tsk_name, $i+1, -1);
            break;
        }
    }
}
 
// 响应内容
return $response;



如果你觉得本篇文章对您有帮助,请打赏作者

上一篇: mysql全文检索中文

下一篇: 最近做的签到功能,记一下这个签到SQL语句

最新评论

暂无评论

热门文章

最新评论

网站数据

网站文章数:481

今日UV/PV/IP:6/8/6

昨日UV/PV/IP:26/29 /25

TOP