thinkphp-queue在使用過程中 遇到的一個教訓
在專案中我們使用了適合於thinphp5
的佇列thinphp-queue
versionv1.1.5
。 正常執行沒有問題,但是每隔一段時間就會有很多工重試。經過排查發現是一個配置的問題。具體可以進入本文來檢視一些事項。
關於 thinkphp-queue 的使用可以見這個網址ofollow,noindex">thinkphp-queue 筆記
我遇到的問題 就是因為一個配置 當我們在thinkphp
的application
應用目錄下建立一個extra/queue.php
時 我們一般這樣建立
return [ 'connector' => 'Database',// 資料庫驅動 'expire'=>60,// 任務的過期時間,預設為60秒; 若要禁用,則設定為 null 'default'=> 'pic',// 預設的佇列名稱 'table'=> 'jobs',// 儲存訊息的表名,不帶字首 //'dsn'=> [], ];
我天真的以為這個任務過期時間時自動刪掉任務的結果不是。
結果通過\think\queue\connector\Database::pop
這個方法的一個判斷得到這樣的結果
if (!is_null($this->options['expire'])) { $this->releaseJobsThatHaveBeenReservedTooLong($queue); }
且\think\queue\connector\Database::releaseJobsThatHaveBeenReservedTooLong
方法是這樣寫的(請注意:這個方法是protected
所以無法在類外部直接呼叫)
protected function releaseJobsThatHaveBeenReservedTooLong($queue) { $expired = time() - $this->options['expire']; $this->db->name($this->options['table']) ->where('queue', $this->getQueue($queue)) ->where('reserved', 1) ->where('reserved_at', '<=', $expired) ->update([ 'reserved'=> 0, 'reserved_at' => null, 'attempts'=> ['inc', 1] ]); }
如果過期時間不是null
, 那麼就重新將任務更新為未執行任務。
於是我悲哀的任務重複執行來了。。。
所以如果你的任務只執行一次,且你想保留任務的話可以將這個設定項expire
設定為null