Desarrollo web

Sala de espera virtual: que la web aguante el día de la venta

Cuando miles de personas quieren comprar a la vez, la web no tiene que aguantarlas a todas: tiene que dejarlas pasar por orden. Así funciona la sala de espera de la plataforma de venta de entradas que desarrollamos.

El reto
Abrir la venta de un evento muy demandado sin que la web se caiga y sin que gane quien más recarga la página.
La solución
Una sala de espera siempre activa, con cola y aforo por evento, un sorteo justo para quien llega antes de la hora y un servicio aparte, mínimo, que atiende a la gente mientras espera.
El resultado
En una prueba con clientes simulados, 30.000 usuarios entraron en la sala en menos de dos minutos y medio, sin un solo error del servidor.

El día que abre la venta de un evento muy esperado, la web recibe en minutos a más gente de la que puede atender. Poner más servidores ayuda, pero no basta: hay que decidir quién compra ahora y quién espera, y conseguir que esperar sea justo y cómodo.

Cómo funciona

  • Siempre activa, con una cola y un aforo por evento. El aforo son «taquilleros virtuales»: cuánta gente puede estar comprando a la vez. Si no hay cola y queda sitio, se entra directamente, sin ver la sala.
  • Se intercepta en la propia aplicación, con un middleware de Laravel. Protege la ficha del evento y el selector de butacas, y el permiso se vuelve a comprobar al crear la reserva.
  • Un proceso permanente da una vuelta cada pocos segundos: deja pasar a los siguientes hasta llenar el aforo y recalcula el puesto de todos los demás.
  • El orden: primero la preventa, después el sorteo de la sala previa y, por último, el orden de llegada.
  • Una rampa de entrada. Hay un tope de admisiones por vuelta para que no entre todo el aforo en el mismo segundo: con aforo 200 y 40 por vuelta, el aforo se llena en unos 25 segundos.

Un sorteo justo para quien llega antes de la hora

Para los eventos más esperados se activa una sala previa, hasta cuatro horas antes de abrir la venta. Antes de la hora no entra nadie y se ve una cuenta atrás; a la hora en punto se sortea el puesto entre todos los que están. No gana quien más recarga la página, y quien llega tarde va detrás.

El primer sorteo usaba el aleatorio de la base de datos y agrupaba a los que habían llegado seguidos. Lo cambiamos por un hash con semilla: en una prueba con 5.000 personas, la relación entre el puesto y el orden de llegada quedó prácticamente en cero.

Un servicio aparte para quien espera

Lo que se satura el día de la venta es la web. Por eso la sala es un servicio aparte y mínimo, en PHP sin framework y en sus propios servidores. No decide nada: lee el puesto que calcula la plataforma y contesta «sigue esperando» o «pasa».

Cada consulta a la sala bajó de unos 6 ms a 1,25 ms de CPU (medido en desarrollo) con tres cambios: configuración precompilada, conexión persistente y una sola ida a Redis por consulta.

El orden lo decide una tabla de MariaDB. Redis, en una base propia, guarda el puesto de cada persona, su último latido y las estadísticas del evento, que caducan solas. Le dimos base propia porque, compartiendo la de las sesiones, los recorridos del proceso se comían la CPU de Redis.

Avisar del turno sin ahogar al servidor

Quien espera pregunta por su turno con un sondeo ligero en JSON, no con websockets. El intervalo depende del puesto: unos 3 segundos para los que están a punto de entrar, entre 8 y 12 hasta el puesto 1.000 y entre 40 y 50 para el resto, nunca más de un minuto. Cada uno lleva un pequeño desfase aleatorio para que no vuelvan todos a la vez.

Es una estimación de diseño, no una medición: con 30.000 personas en cola y aforo 200, salen unas 840 consultas por segundo en lugar de 3.000.

La sala funciona sin JavaScript, recarga la página entera si falla varias veces seguidas y su cuenta atrás usa la hora del servidor, no la del móvil. Cuando toca, aparece «¡Te toca!» y la página redirige sola.

Esperar sin perder el tiempo

Mientras espera, cada persona ve su puesto, cuánta gente tiene delante y detrás, el ritmo de la cola, la ficha del evento con sus precios y la disponibilidad en cinco niveles. Con «Prepara tu compra» elige zona y cantidad, y al entrar se le reservan solas las mejores butacas disponibles.

  • El sitio es de la persona, no de la sesión. Cada una tiene su propio identificador de cola: con el de la sesión, quien iniciaba sesión mientras esperaba perdía su sitio.
  • El pase no dura un tiempo fijo: se pierde por inactividad. Como elegir butacas no genera peticiones, la ficha manda un latido mientras se usa, y ese latido va a la sala y no a la web, porque con la web saturada llegaba tarde. Con el latido nuevo, después de la avalancha de la prueba ningún admitido perdió el turno; antes, lo perdieron 61.
  • Pausa si se agota. Si se acaban las entradas no entra nadie más, pero los que esperan conservan el puesto, y si se liberan entradas la cola sigue sola. Nació de una prueba en la que la cola retenía a cientos de personas para un evento ya agotado.

Saltarse la cola

Sin entrar en detalles: la sala no deja pasar a nadie por sí misma, la plataforma vuelve a comprobar el permiso en cada página protegida y al reservar, el turno caduca y recargar no adelanta.

Hubo también una decisión consciente: no limitar por IP. Con el NAT de las operadoras móviles, miles de compradores reales comparten la misma dirección, y habríamos castigado justo a quien queríamos atender.

Lo que dijeron las pruebas de carga

Probamos en producción con clientes simulados:

  • 30.000 usuarios entraron en la sala en 2 minutos y 25 segundos: 521.558 peticiones y ningún error del servidor.
  • 10.000 clientes llegando a unos 55 por segundo: 91.076 peticiones, todas correctas. En el 95 % de los casos, la ficha respondió en 200 ms y la reserva en 2 segundos.
  • En la avalancha, la web llegó al 91-100 % de CPU y la sala se quedó en el 22-33 %. Justo el reparto que buscábamos.

Y de ahí salieron cambios: un alta en la cola más barata (el puesto lo pone el proceso y, mientras tanto, la sala muestra «calculando») y la eliminación de un recuento que crecía con el cuadrado del tamaño de la cola.

Lo que aprendimos

La web no tiene que aguantar a todos: tiene que dejarlos pasar por orden. Separar la espera de la compra es lo que permite que la compra funcione.

  • Un proceso que se cuelga, mejor matarlo y relanzarlo que intentar arreglarlo desde dentro. El de la cola lo vigila un guardián que lo mata si una vuelta se cuelga, y el supervisor lo relanza. Lo decidimos tras cuatro cuelgues con causas distintas.
  • Medir antes del día de la venta: casi todas las mejoras salieron de las pruebas de carga, no de suposiciones.

¿Te pasa algo parecido?

Cuéntamelo y te digo cómo lo haría, cuánto tardaría y cuánto costaría, sin compromiso.

Sigue leyendo

Correo Cómo dejé el correo de mi dominio en 10/10 en mail-tester Integraciones Un ERP de transporte que habla con el puerto de Valencia
Contacto

¿Hablamos?

¿Tienes una idea por construir, una plataforma que se ha quedado corta o una red que da sustos? Cuéntamelo. Te digo cómo lo haría, cuánto tardaría y cuánto costaría, sin compromiso.

O escríbeme directamente: