概述这是Swoole学习的第二篇文章:SwooleTask的应用。第一篇:SwooleTimerSwoole异步任务的应用,主要实现调用异步任务的执行。常用场景:异步支付处理、异步订单处理、异步日志处理、异步发送邮件/短信等。Swoole的实现是worker进程处理数据请求,分配给task进程执行。官方介绍:任务底层使用UnixSocket管道通信,全内存,无IO消耗。单进程读写性能可达100万/s,不同进程使用不同的管道进行通信,可以最大限度的利用多核。本地版本:PHP7.2.6,Swoole4.3.1。话不多说,先看效果图:代码server.phpserv=newswoole_server('0.0.0.0',9501);$this->serv->set(['worker_num'=>2,//开启2个worker进程'max_request'=>4,//设置每个worker进程的max_request为4倍'task_worker_num'=>4,//开启4个任务进程'dispatch_mode'=>2,//数据包分发策略-固定模式]);$this->serv->on('开始',[$this,'onStart']);$this->serv->on('Connect',[$this,'onConnect']);$this->serv->on("接收",[$this,'onReceive']);$this->serv->on("关闭",[$this,'onClose']);$this->serv->on("任务",[$this,'onTask']);$this->serv->on("完成",[$this,'onFinish']);$this->serv->start();}publicfunctiononStart($serv){echo"####onStart####".PHP_EOL;回声“SWOOLE”.SWOOLE_VERSION。“服务开始”.PHP_EO升;echo"master_pid:{$serv->master_pid}".PHP_EOL;echo"manager_pid:{$serv->manager_pid}".PHP_EOL;echo"########".PHP_EOL.PHP_EOL;}publicfunctiononConnect($serv,$fd){echo"####onConnect####".PHP_EOL;echo"Client:".$fd."Connected".PHP_EOL;echo"########".PHP_EOL.PHP_EOL;}publicfunctiononReceive($serv,$fd,$from_id,$data){echo"####onReceive####".PHP_EOL;echo"worker_pid:{$serv->worker_pid}".PHP_EOL;echo"客户端:来自{$fd}的电子邮件:{$data}".PHP_EOL;$param=['fd'=>$fd,'email'=>$data];$rs=$serv->task(json_encode($param));if($rs===false){echo"任务分配失败任务".$rs.PHP_EOL;}else{echo"任务分配成功任务".$rs.PHP_EOL;}echo"########".PHP_EOL.PHP_EOL;}publicfunctiononTask($serv,$task_id,$from_id,$data){echo"####onTask####".PHP_EOL;echo"#{$serv->worker_id}onTask:[PID={$serv->worker_pid}]:task_id={$task_id}".PHP_EOL;//业务代码for($i=1;$i<=5;$i++){sleep(2);echo"Task{$task_id}已经完成了{$i}/5的任务".PHP_EOL;}$data_arr=json_decode($data,true);$serv->send($data_arr['fd'],'Email:'.$data_arr['email'].',发送成功');$serv->finish($data);echo"########".PHP_EOL.PHP_EOL;}publicfunctiononFinish($serv,$task_id,$data){echo"####onFinish####".PHP_EOL;echo"任务{$task_id}已完成".PHP_EOL;echo"########".PHP_EOL.PHP_EOL;}publicfunctiononClose($serv,$fd){echo"ClientClose.".PHP_EOL;}}$server=newServer();client.phpclient=newswoole_client(SWOOLE_SOCK_TCP,SWOOLE_SOCK_ASYNC);$this->client->on('Connect',[$this,'onConnect']);$this->client->on('Receive',[$this,'onReceive']);$this->client->on('Close',[$this,'onClose']);$this->client->on('Error',[$this,'onError']);}publicfunctionconnect(){if(!$fp=$this->client->connect("127.0.0.1",9501,1)){echo"错误:{$fp->errMsg}[{$fp->errCode}]".PHP_EOL;返回;}}publicfunctiononConnect($cli){fwrite(STDOUT,"输入Email:");swoole_event_add(STDIN,function(){fwrite(STDOUT,"输入Email:");$msg=trim(fgets(STDIN));$this->send($msg);});}publicfunctiononReceive($cli,$data){echoPHP_EOL."Received:".$data.PHP_EOL;}publicfunctionsend($data){$this->client->send($data);}publicfunctiononClose($cli){echo"客户端关闭连接".PHP_EOL;}公共函数onError(){}}$client=newClient();$client->connect();小结1、以上配置开启了多少个进程?一共8个进程(1个master进程,1个manager进程,4个task进程,2个worker进程)可能和上图中的进程号不一致:master进程:22481manager进程:22485task进程:22488、22489、22490,22491workerprocess:22492,22493参考官方进程图:2.为什么执行5次后worker进程号变了?因为我们设置了worker进程的max_request=4,一个worker进程在完成最大请求数的任务后会自动退出,进程退出会释放所有内存和资源。这个机制主要是为了解决PHP进程内存溢出的问题。当任务执行异常时,如果我们kill掉一个任务进程,会不会再增加一个?会议。4.如何设置task_worker_num?最大值不能超过SWOOLE_CPU_NUM*1000。查看本地CPU核数:echo"swoole_cpu_num:".swoole_cpu_num().PHP_EOL;根据项目的任务量来定,比如:1秒会产生200个任务,每个任务执行需要500ms。如果要在1秒内完成200个任务,则需要100个任务进程。100=200/(1/0.5)5.如何设置worker_num?默认设置为机器的CPU核数,最大值不能超过SWOOLE_CPU_NUM*1000。例如:1个请求耗时10ms,要提供1000QPS的处理能力,需要配置10个进程。10=0.01*1000假设每个进程占用40M内存,10个进程需要占用400M内存。ExtendedServer->taskwaitServer->taskWaitMultiServer->taskCo参考文档https://wiki.swoole.com/wiki/...推荐阅读系统讲解-SSO单点登录系统讲解-PHPWEB安全防御系统讲解-PHP缓存技术体系详解-PHP接口签名校验系统详解-与PHP浮点高精度运算一起学习
