PHP 使用redis队列批量发送

收集了一批微信小程序的订阅消息,现在要发送

如果直接从数据库中获取,循环发送,数量不多还好,数量一多,将极大占用服务器资源,甚至造成卡顿。

这个时候就要用到redis的队列异步发送了。

直接上代码,本示例使用YII2框架

        //获取数据
        $subArr=XcxSubscribe::find()->where(['title'=>$title,'status'=>0])->orderBy('id desc')->asArray()->all();
        //将数据插入队列
        $redis=Yii::$app->redis;
        $redis->select(2);//选择redis数据库
        if (!empty($subArr)){
            foreach ($subArr as $k=>$v){
                 $redis->rpush($title,json_encode($v));//将每一条数组插入到队列,等待发送
            }
        }else{
            return Json::encode(['code'=>400,'msg'=>'无数据']);
        }

        $messages=$redis->lrange($title,0,-1);//将队列中的数据取出来
        //var_dump($messages);exit;

        if (!empty($messages)){
            //循环发送
            foreach ($messages as $k=>$v){
                $message=json_decode($v,true);
                $dataArr=array(
                    "touser"=>$message['openid'], //接收用户的openid
                    "template_id"=>$message['template_id'],  //模板id
                    "page"=>$message['page'],//点击模板消息跳转至小程序的页面   支持带参数,(示例index?foo=bar)
                    "data"=>$conArr
                );

                //var_dump($dataArr);exit;
                $res=$this->curl($subscribeUrl,$params=json_encode($dataArr),$ispost=1,$https=1); 
                //失败
                if (stripos($res,'4')){
                    //失败的
                    array_push($openidArr,$message['openid']);
                }else{
                    //成功的
                    array_push($sopenidArr,$message['openid']);
                }

                //从队列中删除
                $redis->lrem($title,0,$v);
            }

            return Json::encode(['code'=>200,'msg'=>'发送成功','data'=>[
                'openidArr'=>$openidArr,
                'sopenidArr'=>$sopenidArr,
            ]]);

        }else{
            return Json::encode(['code'=>400,'msg'=>'队列中无数据']);
        }