Laravel 5.5队列优化:如何按需处理队列并检查运行状态?
Absolutely! Laravel gives you plenty of tools to handle queues on-demand and check their status—let's break this down step by step:
1. Manually Trigger Queue Processing
Instead of relying on Supervisor's fixed polling, you can trigger queue jobs on-demand using either Artisan commands or direct code calls:
Using Artisan Commands
The queue:work --once command is perfect for this—it processes one pending job and then exits immediately. You can tweak it with additional parameters:
php artisan queue:work --once --queue=your-queue-name: Target a specific queuephp artisan queue:work --once --max-jobs=5: Process up to 5 jobs before exitingphp artisan queue:work --once --timeout=60: Set a 60-second timeout for job execution
Using Code (Programmatic Trigger)
You can also call queue processing directly from your controllers, custom commands, or service classes using the Queue facade:
use Illuminate\Support\Facades\Queue; // Process the next job in the default queue Queue::work('default', ['maxJobs' => 1]); // Or process all pending jobs (use cautiously to avoid overload) Queue::work('default', ['maxJobs' => null]);
2. Check if a Queue Worker is Running or Jobs are Being Processed
Laravel doesn't have a single "check worker status" function out of the box, but there are reliable ways to track this:
Option 1: Use queue:status (Laravel 8+)
Laravel 8 introduced the queue:status Artisan command, which returns details about your queues including pending jobs, delayed jobs, and running workers. You can call this programmatically:
use Illuminate\Support\Facades\Artisan; Artisan::call('queue:status'); $statusOutput = Artisan::output(); // Parse the output to check for running workers or pending jobs // Example output might look like: "Default queue: 3 pending, 0 delayed, 1 running worker" if (str_contains($statusOutput, 'running worker')) { // A worker is already active }
Option 2: Track Worker State with Cache/Database
You can listen to Laravel's queue events to mark when a worker starts/stops, then check that state later:
- Register the event listeners in your
App\Providers\AppServiceProvider:
use Illuminate\Queue\Events\WorkerStarted; use Illuminate\Queue\Events\WorkerStopped; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Event; public function boot() { // Mark worker as running when it starts Event::listen(WorkerStarted::class, function () { // Set a 5-minute expiration to handle unexpected crashes Cache::put('queue_worker_active', true, now()->addMinutes(5)); }); // Clear the mark when worker stops Event::listen(WorkerStopped::class, function () { Cache::forget('queue_worker_active'); }); }
- Then check the state wherever you need:
if (!Cache::has('queue_worker_active')) { // No active worker—safe to trigger on-demand processing }
Option 3: Check Supervisor Status (If You're Still Using It)
If you're keeping Supervisor for some workers, you can run the Supervisor CLI command to check status:
// Replace "your-worker-group" with your actual Supervisor worker name $status = shell_exec('supervisorctl status your-worker-group'); if (str_contains($status, 'RUNNING')) { // Supervisor-managed worker is active }
Note: Make sure your web/server user has permission to run supervisorctl for this to work.
3. Example: On-Demand Queue Workflow
Putting it all together, here's how you might implement an on-demand handler:
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Queue; public function handleQueueOnDemand() { // Check if no worker is running if (!Cache::has('queue_worker_active')) { // Check if there are pending jobs (optional) $pendingJobs = \Illuminate\Support\Facades\DB::table('jobs')->count(); if ($pendingJobs > 0) { // Process up to 10 jobs before exiting Queue::work('default', ['maxJobs' => 10]); } } }
4. Bonus: Ditch Polling Entirely (If Possible)
If you're using the database queue driver (which requires polling), consider switching to a driver like Redis or Beanstalkd. These drivers support real-time job pushing—workers will wake up immediately when a job is added, no polling required. This is far more efficient than fixed-interval polling.
内容的提问来源于stack exchange,提问作者Pankaj

