DEV Community

Cover image for Mastering Background Job Processing with Supervisor and Laravel Queues
Md. Asif Rahman
Md. Asif Rahman

Posted on

Mastering Background Job Processing with Supervisor and Laravel Queues

In complex systems where large-scale background processing is essential—like fetching weather data for multiple cities or processing customer transactions —tools such as Supervisor and Laravel queues are indispensable. They help you manage long-running processes efficiently, ensuring jobs run continuously, restart automatically when they fail, and scale dynamically. This article dives deep into how Supervisor works, including its interaction with the Linux kernel, and explores how to optimize job processing for maximum performance.

What is Supervisor, and Why Should You Care?

Supervisor Overview

Supervisor is a process control system that helps manage background processes on Unix-based systems. Think of it as a system manager that:

  • Ensures jobs continue running.
  • Restarts jobs if they fail.
  • Logs output and errors for easier debugging.
  • Monitors system resources to prevent overload.
  • It's like having an experienced manager who ensures tasks in your team are executed and adjusted when things go wrong.

Key Features of Supervisor

  • Process Management: Supervisor keeps processes running by starting, stopping, and restarting them when needed. It ensures long-running tasks stay up and running, even after crashes or failures.

  • Logging: It tracks the output and error logs of processes, which helps in debugging and monitoring.

  • Notifications: Alerts you when a process crashes or restarts, providing vital insights into system health.

  • Scalability: You can configure multiple worker processes (instances) to handle high loads and ensure timely task processing.

Still, if you are not clear about what Supervisor is, have a look on the following analogy to grab it well in mind.

Analogy: Supervisor as a Factory Manager

Imagine a factory that manufactures cars. The factory has multiple assembly lines (processes), and the manager (Supervisor) ensures each line is operational:

Each Line (Process): Handles a specific task—such as assembling the chassis, attaching the wheels, and painting the car.

The Manager: Ensures the lines are always active. If a worker (process) falls behind or crashes, the manager replaces them. When the workload increases (more cars to build), the manager hires more workers (processes).

I hope now, you are totally clear about what supervisor actually is.

Now, lets have a dive into how it works on the kernel level.

How Supervisor Works on the Kernel Level

Supervisor interacts closely with the Linux kernel to manage system resources effectively. Understanding this interaction is crucial for optimizing Supervisor's performance.

Kernel Process Management

At its core, the Linux kernel is responsible for managing system resources, such as:

  • Process Scheduling: Determines which processes get CPU time and for how long.
  • Resource Allocation: Ensures each process gets access to memory and CPU without interfering with others.
  • Process Termination and Restart: The kernel tracks processes and terminates or restarts them if necessary.

Supervisor’s Interaction with the Kernel

  • Supervisor Process: Supervisor itself is a process managed by the kernel. It spawns other processes (workers) and monitors their state using kernel system calls.

  • Process Control: Supervisor uses the kernel’s process control functions to start, stop, and restart worker processes based on your configuration (e.g., autostart=true and autorestart=true).

  • Resource Management: Supervisor can adjust the number of worker processes (using numprocs) based on system resources like available CPU cores and memory. It can also set resource limits to prevent workers from overconsuming resources.

  • Kernel Signals: When a process crashes or stops, Supervisor sends kernel signals (SIGTERM to stop, SIGKILL to forcefully kill) to handle failed workers.

How to Set Up Supervisor for Laravel Queues

Basic Configuration

To configure Supervisor for Laravel queue workers, follow these steps:

  1. Create a configuration file at /etc/supervisor/conf.d/laravel-worker.conf.

  2. Add the following setup to the configuration file:

    [program:laravel-worker]
    command=php /path/to/your/laravel/artisan queue:work --sleep=3 --tries=3
    autostart=true
    autorestart=true
    stderr_logfile=/var/log/laravel-worker.err.log
    stdout_logfile=/var/log/laravel-worker.out.log
    numprocs=4
    process_name=%(program_name)s_%(process_num)02d
    

Explanation

  • command: Specifies the command to run the Laravel queue worker.

    • Example: php artisan queue:work executes the Laravel queue.
  • numprocs: Defines how many worker processes should run simultaneously.

    • Example: Setting numprocs=4 runs four worker processes.
  • autostart and autorestart: Ensure that workers:

    • Start automatically when Supervisor starts.
    • Restart automatically if they crash.
  • stderr_logfile and stdout_logfile: Specify log files for:

    • Error logs (e.g., /var/log/laravel-worker.err.log).
    • Standard output logs (e.g., /var/log/laravel-worker.out.log).
  • process_name: Uniquely identifies each worker process.

    • Example: Workers are named laravel-worker_00, laravel-worker_01, etc., based on the process_num.

Save and Apply Configuration

  1. Save the configuration file.

  2. Update Supervisor to recognize the new configuration:

    sudo supervisorctl reread
    sudo supervisorctl update
    sudo supervisorctl start laravel-worker:*
    

Monitor Workers

To check the status of your workers, use:

sudo supervisorctl status
Enter fullscreen mode Exit fullscreen mode

What Happens When You Have Too Many Jobs?

Let’s consider an example where you are processing 100 jobs (e.g., fetching weather data for 100 cities), but your Supervisor configuration only allows 13 workers (numprocs=13). Here’s how the system manages it:

1. FIFO Queueing

  • Supervisor handles jobs using a First In, First Out (FIFO) queue.
  • With 13 workers, only 13 jobs can run simultaneously, while the remaining 87 jobs wait in the queue.

2. Batch Processing

  • Once a worker completes a task, it immediately picks up another job from the queue.
  • This creates a continuous cycle where jobs are processed in batches until all are completed.

3. Time to Completion

To calculate the approximate total time required to process all jobs, use this formula:

  • Total Jobs: 100
  • Number of Workers: 13
  • Time per Job: 5 seconds
Total Time = (Total Jobs ÷ Number of Workers) × Time per Job
Total Time = (100 ÷ 13) × 5 = ~38.46 seconds
Enter fullscreen mode Exit fullscreen mode

Does numprocs Equal CPU Cores?

No, numprocs does not directly correlate with CPU cores.

For CPU-Intensive Tasks:

If your tasks are CPU-bound (e.g., data processing, video encoding), the number of workers should be limited to the number of available CPU cores to avoid overloading the system.

For I/O-Intensive Tasks:

If your tasks are I/O-bound (e.g., making API calls, reading from disk), you can run more workers than the number of cores, since these tasks spend much of their time waiting for I/O operations to complete.

Example:

  • On an 8-core machine, you might run 16 workers for API-heavy jobs.

To check the number of CPU cores:

nproc   # Shows the number of CPU cores.
lscpu   # Provides detailed CPU information.
Enter fullscreen mode Exit fullscreen mode

Scaling Your Job Processing in Laravel

Scaling your job processing setup ensures your system remains responsive under heavy workloads. Below are key strategies for scaling:

1. Add More Workers

Increase the number of worker processes (numprocs) to handle more jobs simultaneously. However, be mindful of resource consumption:

numprocs=20
Enter fullscreen mode Exit fullscreen mode

Ensure the server has adequate resources (CPU, memory) to handle the extra load.

2. Prioritize Critical Jobs

You can create separate queues for different job priorities. This ensures that critical tasks are processed first:

[program:high-priority-worker]
command=php artisan queue:work --queue=high
numprocs=6

[program:low-priority-worker]
command=php artisan queue:work --queue=low
numprocs=7
Enter fullscreen mode Exit fullscreen mode

3. Scale Horizontally

Distribute job processing across multiple servers to balance the load. Use a shared queue system like Redis to allow all servers to pull jobs from the same queue:

  • Set up multiple Supervisor instances on different servers.
  • Use a distributed queue (e.g., Redis) to synchronize jobs between servers.

4. Monitor and Adjust Configurations

Use tools like Laravel Horizon to monitor your queue workers' performance in real-time. Horizon provides visual insights into job processing, queue lengths, and resource consumption, allowing you to fine-tune configurations as needed.

Finally, given below is a pictorial presentation on how supervisor works:

Image description

Conclusion

Supervisor is a powerful tool for managing background processes in large-scale systems. When paired with Laravel’s queue system, it ensures tasks are processed efficiently and reliably, even during peak workloads. By understanding its configuration options, interaction with the Linux kernel, and scaling strategies, you can optimize job processing, ensuring minimal downtime and smooth operations for your users.

By following best practices and leveraging tools like Laravel Horizon and Redis, you can ensure your system remains responsive, scalable, and reliable.

Top comments (0)