欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

php+swoole实现异步任务处理

程序员文章站 2022-05-18 14:50:51
...

首先安装swoole扩展;
php+swoole实现异步任务处理
书写我们的服务端

$serv = new \Swoole\Server("127.0.0.1", 9501);

        //设置异步任务的工作进程数量
        $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(Redis::lpop('zf'));
            
        });

        //处理异步任务(此回调函数在task进程中执行)
        $serv->on('task', function ($serv, $task_id, $from_id, $data) {
        	//统一通过json字符串的形式进行传参
            $data=json_decode($data,1);
			

            //返回任务执行的结果
            $serv->finish("OK");
        });

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

        $serv->start();

主要就是上面的服务端的设置,接下来是客户端的设置,如果你是通过redis等消息中间件来进行传值,可以通过轮询队列的值来进行异步任务的投递,如果你是通过客户端的传值,就需要书写客户端;

//swoole客户端连接服务端,项目进程处理
          //swoole客户端,通过TCP协议连接
         $client=new \Swoole\Client(SWOOLE_SOCK_TCP);

         //设置异步任务的工作进程数量
         $client->set(array(

             'buffer_output_size' => 32 * 1024 *1024,

         ));

         $client->connect('127.0.0.1','9501',-1);
         
         if(!$client){
             //连接不成功
             //echo "连接服务失败,错误类型为:".$client->errCode.PHP_EOL;
              $data = array(
                 'result' => 'false',
                 'message' => "连接服务失败,错误类型为:".$client->errCode.PHP_EOL
             );
             echo json_encode($data);
             die;
         }
		
		//通过队列传值
		/*
         $redisstr=json_encode($redis);

         Redis::rpush('zf', $redisstr);
         */
		
		//通过客户端发送消息
         
         //发送数据
         $client->send('传输的数据,必须为字符串格式');
         
         //接收服务端的数据
         $res=$client->recv();

         $client->close();