眾所周知,PHP沒有多線程這種東西,雖然也可以實現非同步,但都是用一些折中的方法來做到的。
總結一下自己這幾天接觸到的PHP非同步呼叫需求和解決方案。
當然,自己是個偽碼農,使用的方法,都是些極端不優雅的笨方法,還有待總結修正提高。
一、一個專利採集分析的系統,需要一個完整的操作介面,一個採集進度的動態進度條。(AJAX)
用AJAX來實現,通過ajax不停地訪問伺服器,,通過setInterval來設定間隔時間,訪問backend.php檔案,獲得已經採集的數量,然後更新頁面相應DOM的內容即可。
jQuery學得不太好,代碼比較醜陋,demo如下:
1 jQuery(document).ready(function($) { 2 3 $('#submit').click(function(){ 4 setInterval("updateMsg()", 1000); 5 $.post('total.php', $('#form1').serialize(), function(data, textStatus){ 6 var new_data = "<p>本次所要採集的專利總數為:" + data + "</p>"; 7 $('#total_area').html(new_data); 8 $('#monitor_area').html('<p>正在初始化資訊監控.....</p>'); 9 }); 10 $.post('test.php',$('#form1').serialize()); 11 return false; 12 });13 14 function updateMsg(){ 15 $.get("backend.php",{},function(data, textStatus){ 16 var now_total = "<p>目前已採集數量:" + data + "</p>"; 17 $("#monitor_area").html(now_total); 18 }); 19 }
二、一個郵件發送提醒的應用。(訊息佇列)
一個報名系統,想在第一時間知道報名者的資訊並與其取得聯絡,並發極低,可能十多天就那麼一條報名資訊。
手機提醒用了發郵件到139的方法。
但是有一個問題,就是將發郵件的代碼寫到使用者提交個人資訊的程式段裡以後,提交的過程會變得非常慢,可能達到3S多,簡直無法忍受。
對於郵件發送這種耗時很長的東西,採用了“隊列”的方法。當然,這個隊列沒有RabbitMQ和ZeroMQ這種東西這麼進階,其實就是將資訊存到資料庫裡,算作是入隊列了,然後設定一個cron來處理資料庫裡的這些資訊,處理了,也就是出隊列的,這也是個笨辦法了。
三、那些聽說過沒有用過的進階方法
1.自然就是到處都是的訊息佇列了,自己用資料庫類比的,只不過是最低端的方法而已,不是針對並發的,若是面對高並發,必然會掛掉。這個時候,用上傳說中的RabbitMQ這些東西,效能應該有極大的提升。還有就是Redis資料庫,用過這個東西,感覺用它的list來做訊息佇列,應該也是非常棒的。
2.CURL的方法,curl_multi據說也是個好東西,但是由於CUROPT_TIMEOUT最小是1,所以用戶端至少要等待1S,這也是硬傷。
3.popen()函數,開啟一個指向進程的管道,該進程由派生給定的 command 命令執行而產生。
pclose(popen("/home/xinchen/backend.php &", 'r'));
4.fsockopen()方法,這個方法要自己拼接處http頭來才行。
5.PHP多進程,其實這個方法自己用過,就是將要處理的大段資料按照for迴圈,用vim處理分成小段,然後在CLI模式下跑
php –f example1.php &php –f example2.php &
用這種笨辦法將PHP的進程放到後台來執行……
後來才知道,原來PHP在*uinx下可以直接pcntl類似於C那樣fork出進程來,才知道了這個方法,在採集資料的時候,挺好用的,配合CURL和fsockopen,速度飛快。可惜,可惜的是,剛爽了一會,然後IP就被封掉了……
這個的處理,還是很方便的。
1 for($i = 0; $i <$intNum; $i++) { 2 $pids[$i] = pcntl_fork();// 產生子進程,而且從當前行之下開試運行代碼,而且不繼承父進程的資料資訊 3 if($pids[$i] == -1) { 4 echo "couldn't fork". "\n"; 5 } elseif(!$pids[$i]) { 6 sleep(1); 7 echo "\n"."第".$i."個進程 -> " . time(). "\n"; 8 //這裡就可以放資訊採集抓取等東西的代碼了。 9 exit(0);//子進程要exit否則會進行遞迴多進程,父進程不要exit否則終止多進程10 }11 }
6.gearman分散式運算,開很多的worker來支援將job分布到不同機器上去執行,這個,自己接觸不到,傳說中了。
參考的那些資料:
1.當然是鳥哥的部落格了,風雪之隅,這幾種非同步方法呼叫都是在他那兒看到的。
2.張宴的部落格,多進程的內容。