《PHP編程:Laravel 4.2 中隊列服務(queue)使用感受》要點:
本文介紹了PHP編程:Laravel 4.2 中隊列服務(queue)使用感受,希望對您有用。如果有疑問,可以聯系我們。
這半個月,我介入重寫了一個微信公眾號后端系統,首次使用了laravel 4.2,以及laravel引以為傲的隊列服務(queue).PHP學習
由于整個系統涉及到多端交互,又有大量語音傳輸、處理的業務,我們在一些地方發現響應時間過長.之前的系統基于node.js和mongoDB,由于node天生便是異步,有守護進程,所以并沒有出現過這個問題,而這次重寫必然要引入異步流程了.Queue進入了我們的視線.PHP學習
根據這一頁幾乎還全是英文的”中文文檔“ ,laravel恰好在4.2版本中剛剛引入了redis作為隊列存儲,這是一個非常好的消息.OK,配景介紹到這里,下面扯扯干貨.PHP學習
laravel中的隊列服務跟其他隊列服務也沒有什么不同,都是最符合人類思維的最簡單最普遍的流程:有一個地方存放隊列信息,一個PHP進程在運行時將任務寫入,另外一個PHP守護進程輪詢隊列信息,將達到執行要求的任務執行并刪除.由于PHP是url驅動的同步語言,自己是阻塞的,所以laravel提供一個守護進程工具來查詢并執行隊列信息也就不足為奇了.PHP學習
Laravel的queue配置文件是 /app/config/queue.php,在 Default Queue Driver 這一項中,可以選擇"sync", "beanstalkd", "sqs", "iron", "redis" 五種驅動器.PHP學習
1. sync是當地調試用的同步驅動器PHP學習
2. beanstalkd 是一個專業隊列服務驅動器:http://kr.github.io/beanstalkd/PHP學習
3. sqs和iron是國外第三方隊列服務PHP學習
4. 最后一項redis給了我們一個使用redis的理由,這樣我們趁便把緩存服務和session服務全部遷移到redis上了.PHP學習
0. 順便說一句,session驅動器千萬別用mysql,處理時間1S不是夢,哎,看誰呢,說的便是你,1S哥!PHP學習
隊列服務需要專門新建任務類,作為獨立類,他們不需要繼承類,因為隊列里的任務在執行的時候,是由PHP守護進程來獨立調用的,當然如果你要use一下別的類再調用,也不會出錯.之前我把很多額外服務獨立到了一個單獨的文件夾 /app/services 里,比如輸入信息驗證 validator,特殊平安驗證模塊等,這次queue類們就位于其中.PHP學習
queue的使用非常簡單,下面便是一個簡單的示例:PHP學習
這就是一個標準的queue壓入流程了.當然,在這里我把CurlJsonQueue類放到了services根目錄下,這個目錄已經被我注冊到composer.json的"autoload"的"classmap"中,是位于頂層命名空間中的,可以直接調用,如果必要調用非頂層命名空間,是可以寫 App\OOXX 的.我們的系統必要大量和微信服務器交互,所以就獨立出來了這個類.PHP學習
class CurlJsonQueue extends BaseController{PHP學習
?public function fire($job, $data)
?{
??$url = $data['url'];
??$json = $data['json'];PHP學習
??parent::base_post_curl($url, $json);PHP學習
??$job->delete();
?}
}
PHP學習
這個類默認的辦法是 fire() ,參數也是固定的兩個 $job 和 $data,由于我在BaseController中封裝了post的curl模塊,所以就調用了一下.另外這里還有一個小坑,當時寫base_post_curl() 的時候用的protected,導致use BaseController無效,必須繼承.PHP學習
通過執行上面的代碼,queue中就被放入了一個新的任務,laravel通過下面的命令開啟守護進程:PHP學習
然后守護進程就開始處置隊列了.此代碼中的PHP命令和artisan文件的路徑請自行調整.PHP學習
大家可能注意到了,我們要使用的這個隊列系統用到了redis和PHP命令行,如果在測試環境,加個開機啟動甚至是手動啟動都可以,但是在生產環境就必要更穩固的工具來守護這兩個程序,我們用的是supervisor,關于supervisor的安裝配置大家可以參考這篇文章: http://blog.segmentfault.com/qianfeng/1190000000532561 注意,文章里有小坑請自行去踩...PHP學習
OK,全部配置好之后,跑起來redis和PHP命令行,整個系統就開始愉快地運行啦~PHP學習
使用感受:PHP學習
隊列服務超好用,之前一次和app的交互流程必要6-7S,異步以后降低到2S以內,基本就是傳輸時間和PHP代碼運行時間了,耗時的特殊操作已經異步了.不過隊列服務默認1S開一個進程檢查一次redis中有沒有可以運行的服務,在阿里云服務器上,大約能占到單核的10%,消耗略大,而且隊列處理時間相對較長,因為沒有了之前同步時候的文件加載福利.不過如果有多個任務,PHP進程是會連續執行的,不會1S執行一個的啦.PHP學習
下面說說坑:PHP學習
1. 由于queue核心類使用了一個特殊函數,導致沒有明確類型的變量會以單元素數組的形式存進json,再存進redis.解決方法就是在每一個要放進去的數據前面加上 ''. .上面的$url和$json由于都已經在前面用引號進行了類型申明,故沒做這一步操作.PHP學習
2. 如果要傳遞url給隊列,系統queue類會在每一個 / 前面加上兩個 \\ .這對于一些特殊操作可能會造成致命影響.(開打趣,有上面那個致命么!)PHP學習
維易PHP培訓學院每天發布《PHP編程:Laravel 4.2 中隊列服務(queue)使用感受》等實戰技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培養人才。