首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Laravel 4.2 隊列服務 實戰心得與避坑指南

     編輯:PHP 綜合知識

專案背景

近半月參與重寫一個微信公眾號後端系統,首次使用 Laravel 4.2 及其引以為傲的隊列服務。系統涉及多端交互、大量語音傳輸與處理,發現回應時間過長。前系統基於 Node.js + MongoDB,Node 天生非同步且有守護進程,無此問題;重寫勢必引入非同步流程,Queue 進入視野。

根據幾乎全英文的「中文文件」,Laravel 4.2 剛引入 Redis 作為隊列儲存,這是極佳消息。

隊列運作原理

Laravel 隊列服務與其他隊列系統無異,符合人類直覺的簡單流程:

  1. 儲存隊列資訊的地方(Redis、Beanstalkd 等)
  2. PHP 進程運行時將任務寫入
  3. 另一 PHP 守護進程輪詢隊列,執行符合條件的任務並刪除

因 PHP 是 URL 驅動的同步阻塞語言,Laravel 提供守護進程工具查詢並執行隊列任務。

隊列驅動器選擇

配置檔 /app/config/queue.php 中的 Default Queue Driver 提供五種驅動:

  • sync:本地除錯用同步驅動
  • beanstalkd:專業隊列服務 官網
  • sqs、iron:國外第三方隊列服務
  • redis:讓我們順便將快取與 Session 服務全遷移至 Redis

插曲: Session 驅動千萬別用 MySQL,處理時間 1 秒起跳,看誰呢,說的就是你,1 秒哥!

任務類別建立與使用

隊列任務需建立獨立類別,無需繼承基類,因守護進程會獨立調用。筆者將額外服務獨立至 /app/services(已註冊至 composer.json 的 autoload.classmap),隊列類亦置於其中。

基本推送範例

use Queue;
Queue::push('CurlJsonQueue', [
    'url'  => $url,
    'json' => $json
]);

此為標準隊列推送流程。CurlJsonQueue 類位於 services 根目錄,屬頂層命名空間可直接調用;若需調用非頂層命名空間,可寫 App\OOXX。系統大量與微信伺服器交互,故獨立此類。

任務類別實作

<?php

class CurlJsonQueue extends BaseController {

    public function fire($job, $data)
    {
        $url  = $data['url'];
        $json = $data['json'];

        parent::base_post_curl($url, $json);

        $job->delete();
    }
}

類別預設方法為 fire(),固定參數 $job 與 $data。筆者於 BaseController 封裝了 POST CURL 模組,故直接調用。小坑: 當時 base_post_curl() 設為 protected,導致 use BaseController 無效,必須繼承。

守護進程啟動與生產環境部署

執行指令啟動守護進程:

php artisan queue:listen

測試環境可手動或開機啟動,生產環境需更穩健工具守護 Redis 與 PHP CLI 進程,筆者採用 Supervisor,安裝配置參考:SegmentFault 文章(文中有小坑請自行踩雷)。

全部配置完成,Redis 與 PHP CLI 跑起來,系統愉快運作!

使用心得

  • 超好用: 原本單次 APP 交互流程 6-7 秒,非同步後降至 2 秒內,耗時操作已異步化。
  • 資源消耗: 預設 1 秒輪詢一次 Redis,阿里雲單核佔用約 10%,消耗略大;隊列處理時間相對較長,因失去同步時的檔案載入優勢。但若有多任務,PHP 進程會連續執行,不會一秒跑一個。

避坑指南

  1. 變數型別問題: Queue 核心類使用特殊函數,導致無明確型別的變數以單元素陣列形式存入 JSON 再存 Redis。解決辦法:每個要放入的資料前加 '' 強制轉字串。上例 $url、$json 已用引號宣告型別,故無此問題。
  2. URL 斜線轉義: 傳遞 URL 給隊列時,系統會在每個 / 前加雙反斜線 \\,對特殊操作可能造成影響。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved