PHP扩展Swoole实现实时异步任务队列示例
本文实例讲述了PHP扩展Swoole实现实时异步任务队列。分享给大家供大家参考,具体如下:
假如要发100封邮件,for循环100遍,用户直接揭竿而起,什么破网站!
但实际上,我们很可能有超过1万的邮件。怎么处理这个延迟的问题?
答案就是用异步。把“发邮件”这个操作封装,然后后台异步地执行1万遍。这样的话,用户提交网页后,他所等待的时间只是“把发邮件任务请求推送进队列里”的时间。而我们的后台服务将在用户看不见的地方跑。
在实现“异步队列”这点上,有人采用MySQL表或者redis来存放待发送的邮件,然后,每分钟定时读取待发送列表,然后处理。这便是定时异步任务队列。但当前提交的任务要一分钟后才能执行,在某些实时性要求应用场景里还是不快。有些场景要求,只有一提交任务,便马上执行,但用户不需要等待返回结果。
本文将探讨用php扩展swoole实现实时异步任务队列的方案。
服务端
在打算放置脚本的目录(你也可以自行新建)新建Server.php,代码如下
serv=newswoole_server("0.0.0.0",9501);
$this->serv->set(array(
'worker_num'=>1,//一般设置为服务器CPU数的1-4倍
'daemonize'=>1,//以守护进程执行
'max_request'=>10000,
'dispatch_mode'=>2,
'task_worker_num'=>8,//task进程的数量
"task_ipc_mode"=>3,//使用消息队列通信,并设置为争抢模式
//"log_file"=>"log/taskqueueu.log",//日志
));
$this->serv->on('Receive',array($this,'onReceive'));
//bindcallback
$this->serv->on('Task',array($this,'onTask'));
$this->serv->on('Finish',array($this,'onFinish'));
$this->serv->start();
}
publicfunctiononReceive(swoole_server$serv,$fd,$from_id,$data)
{
//echo"GetMessageFromClient{$fd}:{$data}\n";
//sendatasktotaskworker.
$serv->task($data);
}
publicfunctiononTask($serv,$task_id,$from_id,$data)
{
$array=json_decode($data,true);
if($array['url']){
return$this->httpGet($array['url'],$array['param']);
}
}
publicfunctiononFinish($serv,$task_id,$data)
{
//echo"Task{$task_id}finish\n";
//echo"Result:{$data}\n";
}
protectedfunctionhttpGet($url,$data)
{
if($data){
$url.='?'.http_build_query($data);
}
$curlObj=curl_init();//初始化curl,
curl_setopt($curlObj,CURLOPT_URL,$url);//设置网址
curl_setopt($curlObj,CURLOPT_RETURNTRANSFER,1);//将curl_exec的结果返回
curl_setopt($curlObj,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($curlObj,CURLOPT_SSL_VERIFYHOST,FALSE);
curl_setopt($curlObj,CURLOPT_HEADER,0);//是否输出返回头信息
$response=curl_exec($curlObj);//执行
curl_close($curlObj);//关闭会话
return$response;
}
}
$server=newServer();
客户端
启动服务后,让我们看看如何调用服务。新建测试文件Client_test.php
client=newswoole_client(SWOOLE_SOCK_TCP);
}
publicfunctionconnect()
{
if(!$this->client->connect("127.0.0.1",9501,1)){
thrownewException(sprintf('SwooleError:%s',$this->client->errCode));
}
}
publicfunctionsend($data)
{
if($this->client->isConnected()){
if(!is_string($data)){
$data=json_encode($data);
}
return$this->client->send($data);
}else{
thrownewException('SwooleServerdoesnotconnected.');
}
}
publicfunctionclose()
{
$this->client->close();
}
}
$data=array(
"url"=>"http://192.168.10.19/send_mail",
"param"=>array(
"username"=>'test',
"password"=>'test'
)
);
$client=newClient();
$client->connect();
if($client->send($data)){
echo'success';
}else{
echo'fail';
}
$client->close();
在上面代码中,url即为任务所在地址,param为所需传递参数。
保存好代码,在命令行或者浏览器中执行Client_test.php,便实现了异步任务队列。你所填写的URL,将会在每次异步任务被提交后,以HTTPGET的方式异步执行。
更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP扩展开发教程》、《PHP网络编程技巧总结》、《phpcurl用法总结》、《PHP数组(Array)操作技巧大全》、《PHP数据结构与算法教程》、《php程序设计算法总结》及《php字符串(string)用法总结》
希望本文所述对大家PHP程序设计有所帮助。