php+swoole 异步队列 redis 队列

前言:纯自己研究的简单结合方式,项目中单个的用过,没一起用过

大佬可以直接对我指指点点

有的自己写的,有的百度大佬们的贡献

交流学习做笔记的作用

客户端

// 抽奖 高并发客户端业务处理
    public function ClientPush($request Request){
         $uid  = $request->post('uid'); // 用户ID
         $activity_id = $request->post('activity_id'); // 活动ID
         // 获取转盘活动 详情 
         $activityInfo = getActivityInfo::get($activity_id);  
         // redis 队列处理
         $redis = New Redis();
         $redis->connect('127.0.0.1',6397,30);  // 服务器IP 端口号 连接时间

         $activity_ranks = "activity_".$activity_id;  // 使用结束记得释放掉对应健名

         // 如果队列长度未超过限制数量 经行相应业务逻辑
         if ($redis->llen($activity_ranks) < $activityInfo['num']) {    
            // 插入到列表的尾部 
            $redis->rPush($activity_ranks, $uid);
            /**
             * 则进行对应业务逻辑
             * 抽奖结果,用户ID 传给服务端处理
             * $activity_res // 抽奖结果
             */
            self::ClientPs($activity_res,$uid);
            
         }else{ // 如果队列长度大于限制数量
            // 则经行对应业务逻辑 
         }
    }
    
    public static function ClientPs($activity_res,$uid){
        //swoole客户端连接服务端,项目进程处理
        //swoole客户端,通过TCP协议连接
        $client=new \Swoole\Client(SWOOLE_SOCK_TCP);
        //设置异步任务的工作进程数量
        $client->set(array(
            'buffer_output_size' => 128 * 1024 *1024,   // 128m字节
        ));
        $client->connect('127.0.0.1','9501',-1);
        if(!$client->isConnected()){
            //连接不成功
            //echo "连接服务失败,错误类型为:".$client->errCode.PHP_EOL;
            $data = array(
                'result' => 'false',
                'message' => "连接服务失败,错误类型为:".$client->errCode.PHP_EOL
            );
            echo json_encode($data);
            die;
        }
        //发送数据  数据传输已通过队列
        $data = [
            'activity_res' => $activity_res,
            'uid'   => $uid,
        ];
        $client->send(json_encode($data)); // 传输的数据,必须为字符串格式
        //接收服务端的数据 服务端send发送的数据
        $res = $client->recv();
        $client->close();  // 关闭连  接
    }

 

服务端

public function SwooleTcp(){
        $serv = new \Swoole\Server("127.0.0.1", 9501);  // TCP服务器

        //设置异步任务的工作进程数量
        $serv->set(array(
            'worker_num' => 1, //一般设置为服务器CPU数的1-4倍
            'daemonize' => 1, //以守护进程执行
            'max_request' => 10000,//最大连接数
            'dispatch_mode' => 2,
            'task_worker_num' => 4, //task进程的数量
            "task_ipc_mode " => 3, //使用消息队列通信,并设置为争抢模式
            "log_file" => "/web/log/swoole.log" ,//所有的输出都会写到日志中
        ));
        //此回调函数在worker进程中执行
        $serv->on('receive', function ($serv, $fd, $from_id, $data) {
            //已经获取到数据,返回让客户端关闭连接
            $serv->send($fd, 'true');
            //因为TCP的连接一次传输的数据最大值默认为2M,可以提供修改,但是由于项目处理的数据非常大,
            //所以这里使用redis的队列来进行传值;这里可以使用轮询队列数据方式,也可以通过客户端请求
            //投递异步任务
            $task_id = $serv->task($data);  // 直接将数据添加到人物列表
        });

        //处理异步任务(此回调函数在task进程中执行)
        $serv->on('task', function ($serv, $task_id, $from_id, $data) {
            //统一通过json字符串的形式进行传参
            $datas = json_decode($data,true);
            $activity_info = $datas['activity_ranks'];  // 结果
            $uid = $datas['uid'];   // 用户ID
            /**
             * 执行数据库操作
             * 我的想法是最好在经行库存修改的时候加个乐观锁
             */
            //返回任务执行的结果
            $serv->finish("OK");
        });

        //处理异步任务的结果(此回调函数在worker进程中执行)
        $serv->on('finish', function ($serv, $task_id, $data) {
            //当异步任务执行完毕后的操作,可以进行通知服务端,或是修改状态等
             
        });

        $serv->start();
    }

你可能感兴趣的:(swoole,php,swoole,redis)