業務描述
在聊yii2-queue之前,先來了解下最近使用queue的業務場景。公司最近需要開發遊戲app熱更新的後臺功能,熱更新的差異包在後臺計算生成,所謂差異包就是用新版本的包對比舊版本的包並把有修改或新增的文件重新組成一個新包。這是個很耗時、很佔cpu和內存(zip壓縮包對比)的操作,所以放到隊列慢慢處理。版本包比較大(大約400MB/個),所以考慮存放在第三方服務,每次計算都從第三方下載回來,生成後重新上傳到第三方服務器
問題
上面業務會引發以下問題:
- 文件上傳或下載到第三方服務器不完整
- yii2-queue運行超時,進程自殺
版本
- yii2-queue: 2.0 , 隊列驅動用的是redis
- redis :測試2.6,生產4.0
- php : 7.1
定位、解決問題過程
在開發調試時,用的都是小包(一般不超過5M)的包進行測試,所以不會出現上面的問題。但是,到對接的時候用大包和計算多個版本的差異包時,耗時長還引發一系列其它問題。因爲前期開發偷懶,沒有對程序的每一步做日誌追蹤,後期排查不到問題。首先出現的、最頭痛的問題是包計算到一半就停了,並且沒有任何錯誤日誌,慌得一匹。
我的第一個反應就是:可能服務器內存或cpu崩了,導致進程被殺。查看服務器後,發現確實佔得很高,但不會把程序殺死。排查了很久,決定重新追蹤程序日誌並且從讓程序斷掉的包入手(因爲程序每次計算這個包時斷掉),所以就出現了以上的第一個問題:文件上傳或下載到第三方服務器不完整,導致zip受損,解壓出錯。這個問題不是今天主要聊的,只簡單總結下,每次上傳或下載完後md5_file和第三方提供的md5對比即可保證文件的完整性。
解決完文件完整性問題後,發現程序被殺的問題還沒解決。正頭疼時,之前追蹤的日誌成功捕獲到有用信息
很明顯,程序超時yii2-queue進程自殺了。查看yii2-queue相關文檔,沒有發現相關說明。只能看源碼有沒有相關參數,結果在Queue.php找到:
/**
* @var int default time to reserve a job
*/
public $ttr = 300;
這個是yii2-queue隊列進程任務的保留工作時長,默認是300s。重新配置即可:
'hotUpdateQueue'=>[
'class' => \yii\queue\file\Queue::class,
'as log' => \yii\queue\LogBehavior::class,
'path' => dirname(dirname(__DIR__)) . '/hotUpdateQueue',
'ttr' => 3600,//保留作業時長
],
或許你還會疑問,前文說的是用redis做驅動,爲什麼這裏的配置是文件驅動?
原因是:yii2-queue的隊列任務與redis 4.0版可能有兼容性(猜測),部分任務數據寫不進去,2.8redis是正常的。所以發佈時,臨時切換爲文件驅動