Colas de tareas en PHP: guía de implementación y optimización

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Trabajo con colas de tareas en PHP: de lo simple a lo complejo



En las aplicaciones web modernas, a menudo surge la necesidad de ejecutar operaciones que consumen muchos recursos o son largas sin obligar al usuario a esperar. Envío de notificaciones por email, generación de informes, procesamiento de imágenes, integración con APIs externas — todas estas tareas son ideales para la ejecución asíncrona. Aquí es donde las colas de tareas (job queues) vienen al rescate. En este artículo, veremos en detalle cómo implementar y optimizar el trabajo con colas en PHP, comenzando con soluciones simples y terminando con herramientas industriales.



¿Qué es una cola de tareas y para qué sirve?



Una cola de tareas (job queue) es un mecanismo que permite posponer la ejecución de algún trabajo para después. En lugar de ejecutar una tarea inmediatamente dentro de una solicitud HTTP, la colocas en una cola. Un worker especial o un grupo de workers extraen las tareas de la cola y las procesan en segundo plano.



Principales ventajas de usar colas:

  • Aceleración de la respuesta al usuario: El usuario recibe una respuesta de inmediato, mientras que el trabajo pesado se ejecuta de forma asíncrona.
  • Escalabilidad: Puedes ejecutar varios workers para el procesamiento paralelo de tareas.
  • Fiabilidad: Si una tarea no se ejecuta (por ejemplo, debido a un error temporal), se puede reintentar más tarde.
  • Descarga del servidor principal: Los procesos en segundo plano no bloquean el procesamiento de nuevas solicitudes HTTP.


Cola simple basada en base de datos



La forma más simple de organizar una cola en PHP es usar una tabla en la base de datos (por ejemplo, MySQL). Este enfoque no requiere instalar software adicional y es ideal para proyectos pequeños.



Paso 1: Creación de la tabla jobs

CREATE TABLE jobs (    id INT AUTO_INCREMENT PRIMARY KEY,    queue_name VARCHAR(255) DEFAULT 'default',    payload TEXT NOT NULL,    status ENUM('pending', 'processing', 'completed', 'failed') DEFAULT 'pending',    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,    available_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,    attempts INT DEFAULT 0);


Paso 2: Agregar una tarea a la cola

function addJob(string $queueName, array $data): void {    $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'password');    $stmt = $pdo->prepare(        "INSERT INTO jobs (queue_name, payload, available_at)          VALUES (?, ?, NOW())"    );    $stmt->execute([$queueName, json_encode($data)]);}

// Ejemplo de usoaddJob('emails', ['to' => 'user@example.com', 'subject' => '¡Hola!']);


Paso 3: Creación del worker (worker.php)

// Bucle infinito para procesar tareaswhile (true) {    $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'password');        // Captura de tarea con bloqueo de fila    $stmt = $pdo->prepare(        "SELECT * FROM jobs          WHERE status = 'pending' AND available_at <= NOW()          ORDER BY id ASC          LIMIT 1 FOR UPDATE"    );    $stmt->execute();    $job = $stmt->fetch(PDO::FETCH_ASSOC);        if ($job) {        // Marcamos como "en procesamiento"        $updateStmt = $pdo->prepare("UPDATE jobs SET status = 'processing' WHERE id = ?");        $updateStmt->execute([$job['id']]);                try {            // Ejecución de la tarea            $data = json_decode($job['payload'], true);            processJob($data);                        // Marcamos como completada            $pdo->prepare("UPDATE jobs SET status = 'completed' WHERE id = ?")                ->execute([$job['id']]);        } catch (Exception $e) {            // Manejo de error            $attempts = $job['attempts'] + 1;            if ($attempts < 3) {                

Blogs

Book Recommendations