php+swoole实现异步任务处理
程序员文章站
2022-05-18 14:50:51
...
首先安装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();