Language:

Buscar

Cómo reemplazar workers tradicionales en Laravel usando Google Pub/Sub

  • Share this:
Cómo reemplazar workers tradicionales en Laravel usando Google Pub/Sub

Hace unas semanas me tocó trabajar en una tarea que parecía bastante simple al principio: procesar acciones pesadas de manera asíncrona en una aplicación Laravel.

Lo típico.

Enviar emails, generar archivos, sincronizar información con APIs externas, procesar imágenes, ejecutar tareas demoradas, etc.

Mi primera reacción fue la misma que probablemente tendría cualquier desarrollador Laravel: usar queues y levantar workers.

Algo como:

php artisan queue:work


Y listo.

Pero apareció el problema real: infraestructura.

El proyecto estaba completamente montado sobre Google Cloud Platform y el equipo quería evitar mantener procesos corriendo permanentemente dentro de VMs o contenedores dedicados solamente para workers.

Y ahí fue donde descubrí que, si ya estás trabajando dentro del ecosistema de Google Cloud, probablemente no necesites administrar workers manualmente.

Google ya tiene un servicio diseñado exactamente para esto: Google Pub/Sub.


El problema real de los workers tradicionales   
 


¿Qué es Google Pub/Sub?



Google Pub/Sub es un servicio de mensajería asíncrona completamente administrado por Google Cloud.

La idea principal es desacoplar quién genera eventos de quién los procesa.

En otras palabras:

  1. una aplicación publica mensajes
  2. otra aplicación los consume
  3. ambas no necesitan conocerse entre sí
  4. ambas pueden ejecutarse en momentos distintos
  5. ambas pueden escalar independientemente

Google define Pub/Sub como un sistema de comunicación asíncrona entre servicios.

Y esa palabra es clave:

Asíncrono


¿Qué significa realmente “asíncrono”?


Cuando hacemos algo síncrono, el flujo espera a que la operación termine.

Por ejemplo:

$user = User::create($data);
                        Mail::to($user)->send(new WelcomeEmail());
                        return response()->json([
                            'success' => true
                        ]);


Aquí el request HTTP queda esperando:     

guardar usuario, generar email, conectarse al proveedor SMTP, enviar email, recién devolver respuesta

Si el proveedor SMTP tarda 5 segundos, el usuario espera 5 segundos.

Eso es procesamiento síncrono.


Con procesamiento asíncrono cambia completamente el flujo:

$user = User::create($data);
PublishWelcomeEmailJob::dispatch($user);
return response()->json([
    'success' => true
]);


Ahora:

  1. se guarda usuario
  2. se publica un mensaje
  3. el request termina inmediatamente
  4. otro proceso ejecutará el trabajo después

El usuario recibe respuesta instantánea.

Y ahí aparece Pub/Sub.   


Cómo funciona Google Pub/Sub


Pub/Sub funciona con tres conceptos principales:

  • Topics
  • Publishers
  • Subscribers

Topic

Un topic es un canal donde se publican mensajes.

Ejemplo:

user-created


O:

send-email

Es simplemente un “tema” de eventos.


Publisher

El publisher es quien envía mensajes al topic.

Por ejemplo Laravel:

$pubSub->topic('send-email')->publish([
    'data' => json_encode([
        'email' => $user->email
    ])
]);


Laravel publica un mensaje y termina.

No procesa nada.

No espera nada.

No ejecuta el trabajo pesado.

Solo envía el evento.


Subscriber

El subscriber es quien escucha el topic y procesa el mensaje.

Por ejemplo:

  • Cloud Run
  • Cloud Functions
  • otro microservicio
  • otro backend
  • un worker serverless

Este subscriber recibe el mensaje y ejecuta el trabajo.


Entonces… ¿quién hace el trabajo pesado?

Depende de tu arquitectura.

Normalmente en Google Cloud se combina con:

  • Cloud Run
  • Cloud Functions
  • GKE
  • otros microservicios

Por ejemplo:

Flujo completo

1. Laravel recibe request

POST /register

 


2. Laravel publica mensaje

{
  "user_id": 10,
  "email": "test@test.com"
}

 


3. Pub/Sub recibe mensaje

El mensaje queda almacenado temporalmente.   
 


4. Subscriber recibe mensaje

Cloud Run o Cloud Function lo consume.   
 


5. Subscriber ejecuta lógica

Mail::to($email)->send(...);

 


6. Subscriber confirma procesamiento

Pub/Sub marca el mensaje como procesado.

 


¿Qué pasa si el subscriber falla?

Aquí aparece una de las mejores partes del sistema.

Pub/Sub tiene retries automáticos.

Si el consumidor falla:

  • el mensaje no se pierde
  • Pub/Sub vuelve a enviarlo
  • puede reintentarse múltiples veces
  • incluso puede enviarse a Dead Letter Queues

Todo esto sin que tengas que construir infraestructura manualmente.


¿Por qué esto puede reemplazar workers tradicionales?

Porque en muchos casos:

Ya no necesitas procesos vivos permanentemente

No necesitas:

php artisan queue:work


corriendo 24/7.

Ahora Google activa instancias automáticamente cuando llegan mensajes.

Eso significa:

  • auto scaling real
  • pago por uso
  • cero administración de workers
  • arquitectura serverless
  • menos DevOps

Diferencia conceptual importante


Queue tradicional

Laravel Queue
   ↓
Redis
   ↓
Worker permanente

 


Pub/Sub

Laravel
   ↓
Pub/Sub
   ↓
Cloud Run / Functions


La diferencia grande es que Google administra toda la capa de mensajería y escalado.


Ventajas reales que encontré usando Pub/Sub


1. Escalado automático

Si llegan:

  • 10 mensajes
  • 1000 mensajes
  • 1 millón de mensajes

Google escala automáticamente los consumidores.


2. Menos infraestructura

No hay:

  • supervisord
  • workers colgados
  • memory leaks
  • reinicios manuales

3. Arquitectura desacoplada

Tu API ya no conoce quién procesa.

Solo publica eventos.

Eso permite:

  • microservicios
  • múltiples consumidores
  • sistemas distribuidos
  • event-driven architecture

Una ventaja enorme: múltiples subscribers

Con queues tradicionales normalmente un job lo procesa un solo worker.

Pero con Pub/Sub:

Topic: user-created


Puede ser consumido por:

  • analytics service
  • email service
  • billing service
  • CRM sync service

Todos al mismo tiempo.

El mismo evento dispara múltiples procesos independientes.

Eso es extremadamente poderoso.


Pull vs Push subscriptions

Pub/Sub soporta dos formas de consumir mensajes.

Pull

Tu aplicación pregunta constantemente:

¿Hay mensajes?
¿Hay mensajes?
¿Hay mensajes?


Muy parecido a workers tradicionales.


Push

Pub/Sub envía automáticamente el mensaje a un endpoint HTTP.

Por ejemplo:

POST https://my-service.com/pubsub-handler


Esto encaja perfecto con:

  • Cloud Run
  • Cloud Functions

Y permite arquitecturas completamente serverless.


¿Es realmente rápido?

Sí.

Google menciona latencias del orden de ~100ms.

En la práctica:

  • eventos
  • emails
  • sincronizaciones
  • webhooks
  • pipelines

funcionan prácticamente en tiempo real.


Casos ideales para usar Pub/Sub

Lo usaría especialmente para:

  • envío de emails
  • procesamiento de imágenes
  • eventos de usuarios
  • sincronización entre microservicios
  • webhooks
  • pipelines de datos
  • notificaciones
  • analytics
  • eventos de dominio

Casos donde quizás NO usaría Pub/Sub

No todo debería resolverse con Pub/Sub.

Por ejemplo:

  • tareas extremadamente secuenciales
  • jobs que requieren orden estricto complejo
  • procesamiento síncrono inmediato
  • tareas pequeñas que no justifican infraestructura distribuida

Incluso Google diferencia Pub/Sub de Cloud Tasks dependiendo del caso de uso.


Integración con Laravel

La integración realmente es bastante simple.

Google ofrece SDK oficial para PHP.

composer require google/cloud-pubsub


Luego:

use Google\Cloud\PubSub\PubSubClient;
$pubSub = new PubSubClient([
    'projectId' => env('GOOGLE_CLOUD_PROJECT'),
]);
$topic = $pubSub->topic('send-email');
$topic->publish([
    'data' => json_encode([
        'email' => $user->email,
    ]),
]);


Y listo.

Laravel publica el evento.

El resto lo maneja la infraestructura.   
 

Acá te dejo un diagrama visual de la arquitectura: 

pub-sub-2.png


La parte más importante que entendí

Pub/Sub no es simplemente “otra queue”.

Es un cambio de mentalidad.

Pasas de:

"ejecutar jobs"


a:

"publicar eventos"


Y eso cambia completamente cómo diseñás sistemas distribuidos.

 

Etiquetas:
Carlos Santiago

Carlos Santiago

Laravel Developer