resources/views/pages/frontend/docs/horizon-colas.md
Última modificación: 24 Oct, 2026

Colas Híbridas & Orquestación Horizon

Mañuti implementa un modelo de procesamiento asíncrono híbrido que combina la velocidad de Redis 7.0 como broker de mensajería en memoria con la persistencia relacional de MariaDB para la auditoría de fallos y el seguimiento de lotes. La orquestación y telemetría de estos workers es gobernada por Laravel Horizon.


1. Topología del Sistema Híbrido

En arquitecturas de alto rendimiento, delegar el almacenamiento de colas completas a MySQL mediante bloqueos de fila (SELECT ... FOR UPDATE) provoca contención de base de datos. Por otro lado, usar Redis exclusivamente para registrar errores implica pérdida de trazabilidad si la memoria se recicla.

Mañuti resuelve esta disyuntiva segregando responsabilidades:

flowchart TD
    REQ["[Petición Web / Controlador]"]
    REDIS["Redis (Memoria RAM)<br/>(Cola de Tránsito / Streaming)"]
    WORKER["Procesamiento del Trabajo"]
    FAIL["[MariaDB: failed_jobs]<br/>(Historial Inmutable)"]
    BATCH["[MariaDB: job_batches]<br/>(Estado Atómico Transaccional)"]

    REQ -->|"1. Dispatch(Job) en microsegundos"| REDIS
    REDIS -->|"2. Worker Horizon consume y procesa"| WORKER
    
    WORKER -->|"(Si falla N veces)"| FAIL
    WORKER -->|"(Progreso de Lote)"| BATCH

2. Configuración del Núcleo (config/queue.php & .env)

El archivo .env establece las conexiones correspondientes:

# Broker de mensajería de colas en tránsito
QUEUE_CONNECTION=redis

# Driver persistente para registrar excepciones definitivas
QUEUE_FAILED_DRIVER=database-uuids

En config/queue.php, el seguimiento de lotes se ancla a MariaDB:

'batching' => [
    'database' => env('DB_CONNECTION', 'mysql'),
    'table'    => 'job_batches',
],

'failed' => [
    'driver'   => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
    'database' => env('DB_CONNECTION', 'mysql'),
    'table'    => 'failed_jobs',
],

3. Configuración y Balanceo en Horizon (config/horizon.php)

Para optimizar recursos en producción, Horizon implementa la estrategia de Auto-Balancing, creando y destruyendo workers de forma elástica según el volumen de la cola:

// config/horizon.php
'environments' => [
    'production' => [
        'supervisor-1' => [
            'connection' => 'redis',
            'queue'      => ['default', 'auditoria', 'imports', 'exports'],
            'balance'    => 'auto', // Ajuste dinámico de procesos
            'minProcesses' => 2,
            'maxProcesses' => 10,
            'balanceMaxShift' => 1,
            'balanceCooldown' => 3,
            'tries'      => 3,
            'timeout'    => 120, // Timeout en segundos por Job
        ],
    ],
],

4. Demonio de Sistema (/etc/supervisor/conf.d/horizon.conf)

Supervisor vigila al maestro de Horizon para garantizar que la cola nunca quede desatendida tras un reinicio del sistema operativo o fallo de memoria:

[program:horizon]
process_name=%(program_name)s
command=/usr/bin/php /var/www/framedev12/artisan horizon
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/framedev12/storage/logs/horizon.log
stopwaitsecs=3600

Nota sobre stopwaitsecs=3600: Este parámetro otorga hasta 1 hora a los workers en ejecución para completar trabajos largos pendientes antes de forzar su terminación (Graceful Shutdown).


5. Control de Acceso al Dashboard de Horizon (RBAC)

El acceso a la interfaz web /horizon no utiliza autenticación básica HTTP ni contraseñas estáticas en .env. Se integra de forma nativa con el sistema de RBAC Aditivo y Permisos:

  1. Se define el permiso horizon.view en la tabla permissions.
  2. Se asocia al rol Super Admin.
  3. El HorizonServiceProvider evalúa la capacidad antes de autorizar el renderizado del dashboard:
// app/Providers/HorizonServiceProvider.php
namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Laravel\Horizon\HorizonApplicationServiceProvider;

class HorizonServiceProvider extends HorizonApplicationServiceProvider
{
    protected function gate(): void
    {
        Gate::define('viewHorizon', function ($user) {
            return $user->can('horizon.view');
        });
    }
}
// config/horizon.php
'middleware' => ['web', 'auth', 'auditar:acceso_horizon'],

Enlaces Relacionados

Edita este documento en >> horizon-colas.md
← Volver a la Landing Page