這篇文章給大家分享的內容是php swoole如何實現非同步任務佇列 ,有著一定的參考價值,有需要的朋友可以參考
假如要發100封郵件,for循環100遍,用戶直接揭竿而起,什麼破網站!
但實際上,我們很可能有超過1萬的郵件。怎麼處理這個延遲的問題?
答案就是用非同步。把「發郵件」這個操作封裝,然後後台異步地執行1萬遍。這樣的話,用戶提交網頁後,他所等待的時間只是「把發郵件任務請求推送進隊列裡」的時間。而我們的後台服務將在用戶看不見的地方跑。
在實作「非同步佇列」這點上,有人採用MySQL表或redis來存放待發送的郵件,然後,每分鐘定時讀取待發送列表,然後處理。這便是定時非同步任務佇列。但目前提交的任務要一分鐘後才能執行,在某些實時性要求高的應用場景裡還是不快,比如發送短信的場景,只要一提交任務,便要馬上執行,用戶不需要等待返回結果。
以下將探討以php擴充swoole實作即時非同步任務佇列傳送簡訊的方案。
服務端
#第二步:設定伺服器的相關屬性
第三步:設定服務端的相關回呼函數處理任務
具體程式碼如下: tcp_server.php
<?php class Server{ private $serv; public function __construct(){ $this->serv = new swoole_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')); $this->serv->on('Task',array($this,'onTask')); $this->serv->on('Finish',array($this,'onFinish')); $this->serv->start(); } public function onReceive(swoole_server $serv, $fd, $from_id, $data){ $serv->task($data); } public function onTask($serv, $task_id, $from_id, $data){ $data = json_decode($data,true); if(!empty($data)){ return $this->sendsms($data['mobile'],$data['message']); } } public function onFinish($serv, $task_id, $data){ echo "Task {$task_id} finish\n"; } public function sendsms($mobile,$text) { $timestamp = date("Y-m-d H-i-s"); $pid = "888888888"; $send_sign = md5($pid.$timestamp."abcdefghijklmnopqrstuvwxyz"); $post_data = array(); $post_data['partner_id'] = $pid; $post_data['timestamp'] =$timestamp; $post_data['mobile'] = $mobile; $post_data['message'] = $text; $post_data['sign'] = $send_sign; $url='http://182.92.149.100/sendsms'; $o=""; foreach ($post_data as $k=>$v) { $o.= "$k=".urlencode($v)."&"; } $post_data=substr($o,0,-1); $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_URL,$url); //为了支持cookie //curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt'); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($ch); if(strpos($result,"success")!==false) { $outstr=1; } else { $outstr=502; } return $outstr; } } $server = new Server(); ?>客戶端#啟動後端服務後,客戶端首先建立tcp客戶端伺服器,然後連接tcp後端伺服器,並向後端tcp伺服器發送數據,具體程式碼如下:client.php
<?php class Client{ public $client; public function __construct(){ $this->client= new swoole_client(SWOOLE_SOCK_TCP);//默认同步tcp客户端,添加参数SWOOLE_SOCK_ASYNC为异步 } public function connect(){ if(!$this->client->connect('127.0.0.1',9501,1)){ throw new Exception(sprintf('Swoole Error: %s', $this->client->errCode)); } } public function send($data){ if($this->client->isConnected()){ $data = json_encode($data); //print $data; if($this->client->send($data)){ return 1; }else{ throw new Exception(sprintf('Swoole Error: %s', $this->client->errCode)); } }else{ throw new Exception('Swoole Server does not connected.'); } } public function close(){ $this->client->close(); } } $client= new Client(); $client->connect(); $data=array( 'mobile'=>'18511487955', 'message'=>'you mobile 18511487955' ); if($client->send($data)){ echo 'succ'; }else{ echo 'fail'; } ?>相關建議: ###PHP使用swoole來實作即時非同步任務佇列#################spring boot-使用redis的Keyspace Notifications實作定時任務佇列##########
以上是利用php +swoole如何實現非同步任務佇列的詳細內容。更多資訊請關注PHP中文網其他相關文章!