2015-04-02 58 views
0

我正在使用Laravel 4.2Laravel 4.2 SQS隊列在後臺使用代碼執行監聽器

我正在處理用戶上傳視頻的項目。爲了使上傳的視頻可用於所有類型的設備,我使用php-ffmpeg包到transcode它。代碼轉換過程非常耗時,因此我決定將其轉換爲背景,並且爲此我使用了Amazon SQS實現了隊列機制。

我在queue.php文件中配置了SQS驅動程序和密鑰,密鑰,URL以及區域。

僅用於測試目的,我在Routes.php中添加了以下代碼。

Route::get('/testasync/{id}', function($id){ 
    Queue::push(function($job) use ($id) { 
     try{ 
      $video_rel = VideoRel::find($id); 
      $video_rel->delete(); 
     } catch(Exception $ex){ 

     } 
     $job->delete(); 
    }); 
    return "hello 1234 world " . $id; 
}); 

所以,每當我會讓一個GET請求來http://mydomainname/testasync/{id}這將推動一個消息隊列從一個特定的模式刪除特定記錄。

令人驚訝的是,我發現隊列將不是被執行,直到我在服務器上執行queue listener

如果我需要在服務器上執行一些操作(例如部署新代碼等)會怎麼樣。在這種情況下,我必須停止聽衆。

另外,我發現的另一個難點是每當我重新執行偵聽器時,它都試圖執行所有的作業。

例如,我對Id 1和2做了兩個Get請求。因此兩個記錄都被刪除。現在,我因爲某種原因停止了監聽器,然後再次請求Id 3。現在,記錄3不會被刪除,直到我使用php artisan queue:listen執行列表器並且如果我執行它,則會拋出2個錯誤method delete called on non-object for Id 1 and 2;並刪除Id 3的記錄。

我不確定它爲什麼發生,因爲已執行的作業必須刪除。

任何人都可以解決?

從代碼中執行監聽器以及在作業完成後停止監聽器會更好。

回答

1

我不確定我是否理解您的期望,但是當您執行Queue :: push時,您將作業發送到隊列,並且只會由偵聽器執行。如果您沒有隊列:listen命令,它將不會運行。如果您希望立即執行作業,則不應將其發送到隊列中。

您不需要停止偵聽器,您可以在超級用戶進程中運行它,它會在超時後自動重新啓動進程。檢查此:http://posts.danharper.me/laravel-queue-supervisor/

現在事實上,關閉隊列後:它試圖執行已經處理的作業似乎真的很奇怪,可能是作業沒有被刪除(嘗試將作業刪除到封閉的開始),但是我需要更多的信息來幫助你調試。

希望這些信息對您有所幫助。

+0

謝謝。我認爲,如果在處理隊列中的代碼時出現異常,則作業不會被刪除。所以每當我啓動隊列監聽器時,它都試圖執行那些有例外的作業。我已經清除了亞馬遜上的隊列,並通過在頂部放置$ job-> delete()來再次嘗試,它已成功運行。 – Dev 2015-04-02 11:51:44

+0

但是,如何維護失敗的隊列作業?例如,如果作業失敗時發生任何錯誤,則再次重新執行該隊列,如果再次失敗,則刪除該作業。可能嗎? – Dev 2015-04-02 11:52:05

+0

頂部的job-> delete()只是一個竅門。當作業沒有失敗時,您只應該調用job-> delete()。請注意,在try/catch中沒有捕獲到php中致命類型的錯誤。如果您不刪除作業,隊列會自動重複處理作業。 如果沒有拋出異常,您可以執行的操作只有刪除作業,並且在關閉開始時可以寫入: if($ job-> attempts()> 3)$ job-> delete(); return; } 選中此項:http://laravel.com/docs/4.2/queues – Shemahmforash 2015-04-02 13:38:31