<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] ## 1、簡介 Lumen隊列服務為各種不同的后臺隊列提供了統一的API。隊列允許你推遲耗時任務(例如發送郵件)的執行,從而大幅提高web請求速度。 #### 1.1 配置 .env文件的QUEUE_DRIVER選項決定應用使用的隊列“驅動”。 #### 1.2 隊列驅動預備知識 數據庫 為了使用`database`隊列驅動,需要一張數據庫表來存放任務,要生成創建該表的遷移,運行Artisan命令`queue:table`,遷移被創建好了之后,使用`migrate`命令運行遷移: ~~~ php artisan queue:table php artisan migrate ~~~ 其它隊列依賴 下面是以上列出隊列驅動需要安裝的依賴: * [Amazon](http://laravelacademy.org/tags/amazon "View all posts in Amazon")?SQS:?`aws/aws-sdk-php ~3.0` * Beanstalkd:?`pda/pheanstalk ~3.0` * IronMQ:?`iron-io/iron_mq ~2.0` * [Redis](http://laravelacademy.org/tags/redis "View all posts in Redis"):?`predis/predis ~1.0` ## 2、編寫任務類 #### 2.1??任務類結構 默認情況下,應用的所有隊列任務都存放在`app/Jobs`目錄。任務類非常簡單,正常情況下只包含一個當隊列處理該任務時被執行的`handle`方法,讓我們看一個任務類的例子: ~~~ <?php namespace App\Jobs; use App\User; use App\Jobs\Job; use Illuminate\Contracts\Mail\Mailer; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Bus\SelfHandling; use Illuminate\Contracts\Queue\ShouldQueue; class SendReminderEmail extends Job implements SelfHandling, ShouldQueue { use InteractsWithQueue, SerializesModels; protected $user; /** * 創建一個新的任務實例 * * @param User $user * @return void */ public function __construct(User $user) { $this->user = $user; } /** * 執行任務 * * @param Mailer $mailer * @return void */ public function handle(Mailer $mailer) { $mailer->send('emails.reminder', ['user' => $this->user], function ($m) { // }); $this->user->reminders()->create(...); } } ~~~ 在本例中,注意我們能夠直接將[Eloquent模型](http://laravelacademy.org/post/138.html)傳遞到對列任務的構造函數中。由于該任務使用了`SerializesModels`?trait,Eloquent模型將會在任務被執行是優雅地序列化和反序列化。如果你的隊列任務在構造函數中接收Eloquent模型,只有模型的主鍵會被序列化到隊列,當任務真正被執行的時候,隊列系統會自動從數據庫中獲取整個模型實例。這對應用而言是完全透明的,從而避免序列化整個Eloquent模型實例引起的問題。 `handle`方法在任務被隊列處理的時候被調用,注意我們可以在任務的`handle`方法中對依賴進行類型提示。Lumen[服務容器](http://laravelacademy.org/post/471.html)會自動注入這些依賴。 出錯 如果任務被處理的時候拋出異常,則該任務將會被自動釋放回隊列以便再次嘗試執行。任務會持續被釋放知道嘗試次數達到應用允許的最大次數。最大嘗試次數通過Artisan任務`queue:listen`或`queue:work`上的`--tries`開關來定義。關于運行隊列[監聽器](http://laravelacademy.org/tags/%e7%9b%91%e5%90%ac%e5%99%a8 "View all posts in 監聽器")的更多信息可以在[下面](http://laravelacademy.org/post/469.html#ipt_kb_toc_469_8)看到。 手動釋放任務 如果你想要手動釋放任務,生成的任務類中自帶的`InteractsWithQueue`?trait提供了釋放隊列任務的`release`方法,該方法接收一個參數——同一個任務兩次運行之間的等待時間: ~~~ public function handle(Mailer $mailer){ if (condition) { $this->release(10); } } ~~~ 檢查嘗試運行次數 正如上面提到的,如果在任務處理期間發生異常,任務會自動釋放回隊列中,你可以通過`attempts`方法來檢查該任務已經嘗試運行次數: ~~~ public function handle(Mailer $mailer){ if ($this->attempts() > 3) { // } } ~~~ ## 3、推送任務到隊列 默認的Lumen控制器位于`app/Http/Controllers/Controller.php`并使用了`DispatchesJobs`?trait。該trait提供了一些允許你方便推送任務到隊列的方法,例如`dispatch`方法: ~~~ <?php namespace App\Http\Controllers; use App\User; use Illuminate\Http\Request; use App\Jobs\SendReminderEmail; use App\Http\Controllers\Controller; class UserController extends Controller{ /** * 發送提醒郵件到指定用戶 * * @param Request $request * @param int $id * @return Response */ public function sendReminderEmail(Request $request, $id) { $user = User::findOrFail($id); $this->dispatch(new SendReminderEmail($user)); } } ~~~ 為任務指定隊列 你還可以指定任務被發送到的隊列。 通過推送任務到不同隊列,你可以對隊列任務進行“分類”,甚至優先考慮分配給多個隊列的worker數目。這并不會如隊列配置文件中定義的那樣將任務推送到不同隊列“連接”,而只是在單個連接中發送給特定隊列。要指定該隊列,使用任務實例上的`onQueue`方法,該方法有Lumen自帶的基類`App\Jobs\Job`提供: ~~~ <?php namespace App\Http\Controllers; use App\User; use Illuminate\Http\Request; use App\Jobs\SendReminderEmail; use App\Http\Controllers\Controller; class UserController extends Controller{ /** * 發送提醒郵件到指定用戶 * * @param Request $request * @param int $id * @return Response */ public function sendReminderEmail(Request $request, $id) { $user = User::findOrFail($id); $job = (new SendReminderEmail($user))->onQueue('emails'); $this->dispatch($job); } } ~~~ #### 3.1?延遲任務 有時候你可能想要延遲隊列任務的執行。例如,你可能想要將一個注冊15分鐘后給消費者發送提醒郵件的任務放到隊列中,可以通過使用任務類上的`delay`方法來實現,該方法由`Illuminate\Bus\Queueable`?trait提供: ~~~ <?php namespace App\Http\Controllers; use App\User; use Illuminate\Http\Request; use App\Jobs\SendReminderEmail; use App\Http\Controllers\Controller; class UserController extends Controller{ /** * 發送提醒郵件到指定用戶 * * @param Request $request * @param int $id * @return Response */ public function sendReminderEmail(Request $request, $id) { $user = User::findOrFail($id); $job = (new SendReminderEmail($user))->delay(60); $this->dispatch($job); } } ~~~ 在本例中,我們指定任務在隊列中開始執行前延遲60秒。 > 注意:Amazon SQS服務最大延遲時間是15分鐘。 #### 3.2 從請求中分發任務 映射HTTP請求變量到任務中很常見,Lumen提供了一些幫助函數讓這種實現變得簡單,而不用每次請求時手動執行映射。讓我么看一下?`DispatchesJobs`?trait上的`dispatchFrom`方法。默認情況下,該trait包含在Lumen控制器基類中: ~~~ <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class CommerceController extends Controller{ /** * 處理指定訂單 * * @param Request $request * @param int $id * @return Response */ public function processOrder(Request $request, $id) { // 處理請求... $this->dispatchFrom('App\Jobs\ProcessOrder', $request); } } ~~~ 該方法檢查給定任務類的構造函數并從HTTP請求(或者其它`ArrayAccess`對象)中解析變量來填充任務需要的構造函數參數。所以,如果我們的任務類在構造函數中接收一個`productId`變量,該任務將會嘗試從HTTP請求中獲取`productId`參數。 你還可以傳遞一個數組作為`dispatchFrom`方法的第三個參數。該數組用于填充所有請求中不存在的構造函數參數: ~~~ $this->dispatchFrom('App\Jobs\ProcessOrder', $request, [ 'taxPercentage' => 20, ]); ~~~ ## 4、運行隊列監聽器 開啟任務監聽器 Lumen包含了一個Artisan命令用來運行推送到隊列的新任務。你可以使用`queue:listen`命令運行監聽器: ~~~ php artisan queue:listen ~~~ 還可以指定監聽器使用哪個隊列連接: ~~~ php artisan queue:listen connection ~~~ 注意一旦任務開始后,將會持續運行直到手動停止。你可以使用一個過程監視器如[Supervisor](http://supervisord.org/)來確保隊列監聽器沒有停止運行。 隊列[優先級](http://laravelacademy.org/tags/%e4%bc%98%e5%85%88%e7%ba%a7 "View all posts in 優先級") 你可以傳遞逗號分隔的隊列連接列表到`listen`任務來設置隊列優先級: ~~~ php artisan queue:listen --queue=high,low ~~~ 在本例中,`high`隊列上的任務總是在從`low`隊列移動任務之前被處理。 指定任務超時參數 你還可以設置每個任務允許運行的最大時間(以秒為單位): ~~~ php artisan queue:listen --timeout=60 ~~~ 指定隊列睡眠時間 此外,可以指定輪詢新任務之前的等待時間(以秒為單位): ~~~ php artisan queue:listen --sleep=5 ~~~ 需要注意的是隊列只會在隊列上沒有任務時“睡眠”,如果存在多個有效任務,該隊列會持續運行,從不睡眠。 #### 4.1?[Supervisor](http://laravelacademy.org/tags/supervisor "View all posts in Supervisor")配置 Supervisor為Linux操作系統提供的進程監視器,將會在失敗時自動重啟`queue:listen`或`queue:work`命令,要在Ubuntu上安裝Supervisor,使用如下命令: ~~~ sudo apt-get install supervisor ~~~ Supervisor配置文件通常存放在`/etc/supervisor/conf.d`目錄,在該目錄中,可以創建多個配置文件指示Supervisor如何監視進程,例如,讓我們創建一個開啟并監視`queue:work`進程的`laravel-worker.conf`文件: ~~~ [program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3 --daemon autostart=true autorestart=true user=forge numprocs=8 redirect_stderr=true stdout_logfile=/home/forge/app.com/worker.log ~~~ 在本例中,`numprocs`指令讓Supervisor運行8個`queue:work`進程并監視它們,如果失敗的話自動重啟。配置文件創建好了之后,可以使用如下命令更新Supervisor配置并開啟進程: ~~~ sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start laravel-worker:* ~~~ 要了解更多關于Supervisor的使用和配置,查看[Supervisor文檔](http://supervisord.org/index.html)。此外,還可以使用[Lumen Forge](https://forge.laravel.com/)從web接口方便地自動配置和管理Supervisor配置。 #### 4.2 后臺隊列監聽器 Artisan命令`queue:work`包含一個`--daemon`選項來強制隊列worker持續處理任務而不必重新啟動框架。相較于`queue:listen`命令該命令對CPU的使用有明顯降低: ~~~ php artisan queue:work connection --daemon php artisan queue:work connection --daemon --sleep=3 php artisan queue:work connection --daemon --sleep=3 --tries=3 ~~~ 正如你所看到的,`queue:work`任務支持大多數`queue:listen`中有效的選項。你可以使用`php artisan help queue:work`任務來查看所有有效選項。 后臺隊列監聽器編碼考慮 后臺隊列worker在處理每個任務時不重啟框架,因此,你要在任務完成之前釋放資源,舉個例子,如果你在使用GD庫操作圖片,那么就在完成時使用`imagedestroy`釋放內存。 類似的,數據庫連接應該在后臺長時間運行完成后斷開,你可以使用`DB::reconnect`方法確保獲取了一個新的連接。 #### 4.3 部署后臺隊列監聽器 由于后臺隊列worker是常駐進程,不重啟的話不會應用代碼中的更改,所以,最簡單的部署后臺隊列worker的方式是使用部署腳本重啟所有worker,你可以通過在部署腳本中包含如下命令重啟所有worker: ~~~ php artisan queue:restart ~~~ 該命令會告訴所有隊列worker在完成當前任務處理后重啟以便沒有任務被遺漏。 > 注意:這個命令依賴于緩存系統重啟進度表,默認情況下,APC在CLI任務中無法正常工作,如果你在使用APC,需要在APC配置中添加`apc.enable_cli=1`。 ## 5、處理失敗任務 由于事情并不總是按照計劃發展,有時候你的隊列任務會失敗。別擔心,它發生在我們大多數人身上!Lumen包含了一個方便的方式來指定任務最大嘗試執行次數,任務執行次數達到最大限制后,會被插入到`failed_jobs`表,失敗任務的名字可以通過配置文件`config/queue.php`來配置。 要創建一個failed_jobs表的遷移,可以使用queue:failed-table命令: ~~~ php artisan queue:failed-table ~~~ 運行[隊列監聽器](http://laravelacademy.org/post/469.html#ipt_kb_toc_469_8)的時候,可以在`queue:listen`命令上使用`--tries`開關來指定任務最大可嘗試執行次數: ~~~ php artisan queue:listen connection-name --tries=3 ~~~ #### 5.1?失敗任務[事件](http://laravelacademy.org/tags/%e4%ba%8b%e4%bb%b6 "View all posts in 事件") 如果你想要注冊一個隊列任務失敗時被調用的事件,可以使用`Queue::failing`方法,該事件通過郵件或[HipChat](https://www.hipchat.com/)通知團隊。舉個例子,我么可以在Lumen自帶的`AppServiceProvider`中附件一個回調到該事件: ~~~ <?php namespace App\Providers; use Queue; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ /** * 啟動應用服務 * * @return void */ public function boot() { Queue::failing(function ($connection, $job, $data) { // Notify team of failing job... }); } /** * 注冊服務提供者 * * @return void */ public function register() { // } } ~~~ 任務類的失敗方法 想要更加細粒度的控制,可以在隊列任務類上直接定義`failed`方法,從而允許你在失敗發生時執行指定動作: ~~~ <?php namespace App\Jobs; use App\Jobs\Job; use Illuminate\Contracts\Mail\Mailer; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Bus\SelfHandling; use Illuminate\Contracts\Queue\ShouldQueue; class SendReminderEmail extends Job implements SelfHandling, ShouldQueue { use InteractsWithQueue, SerializesModels; /** * 執行任務 * * @param Mailer $mailer * @return void */ public function handle(Mailer $mailer) { // } /** * 處理失敗任務 * * @return void */ public function failed() { // Called when the job is failing... } } ~~~ #### 5.2?重試失敗任務 要查看已插入到`failed_jobs`數據表中的所有失敗任務,可以使用Artisan命令`queue:failed`: ~~~ php artisan queue:failed ~~~ 該命令將會列出任務ID,連接,對列和失敗時間,任務ID可用于重試失敗任務,例如,要重試一個ID為5的失敗任務,要用到下面的命令: ~~~ php artisan queue:retry 5 ~~~ 如果你要刪除一個失敗任務,可以使用`queue:forget`命令: ~~~ php artisan queue:forget 5 ~~~ 要刪除所有失敗任務,可以使用`queue:flush`命令: ~~~ php artisan queue:flush ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看