Cómo sobrevivir a un concurso online



Luego de finalizar el concurso de Oscars 2018 quería hacerles una especie de resumen de todos los problemas y las soluciones que le encontré a cada uno. Recuerden que este es un blog pequeño con un servidor relativamente pequeño y sin un equipo de soporte salvo yo mismo en mis tiempos libres :D así que me las tuve que rebuscar para poder "soportar" el tráfico y la incesante cantidad de F5 que le dieron duro al servidor durante varias horas.

Pero no sólo tuve que resolver eso puntual, además tuve que preparar el sitio para poder asimilar muchos más usuarios de lo habitual, el registro y varias cosas que hacía rato que no revisaba. Recuerden que no tengo un sistema "común" y que, además, hay porciones de código que datan de hace 15 años :D y todavía funcionan (no tengo idea por quéGuiño.

Si trabajás en una agencia y te piden hacer algo parecido, tal vez este post te pueda servir como referencia...



Preparación



Aclaro algo, me había olvidado de la fecha exacta de los Oscars, arranqué todo mucho más tarde de lo habitual por lo que me costó tener cerrado el tema premios y promoción, aun así logramos que más de 560 personas se sumaran al concurso con apenas 6 días para participar y gracias a Motorola que se copó tuvimos un premio más que suculento. Gracias a ellos.

La promoción del concurso la hice enviando mailing a los que habían participado de los concursos anteriores y en los comentarios del blog durante 2017-18, así no era spam para todo el mundo. Utilicé Mailchimp para que tengan más control de su suscripción y para poder medir cuánto funcionaba.

Como no quería ser un acosador spammer hice sólo dos campañas a unos 1200 receptores, la primera tuvo 32% de apertura y 12% de clicks, la segunda como aviso de "ya termina" tuvo 20% de apertura, 4% de clicks. Dentro de los márgenes esperados. No envié a todos los usuarios del blog porque algunos no entran aquí hace una década y porque Mailchimp tiene un límite de 2000 usuarios antes de garpar y... lo uso una vez al año para ESTE concurso nada más... no daba. Si vas a hacer concursos masivos, es una excelente herramienta.

Registro de usuario



El primer problema era arreglar el registro de usuario. Funcionaba para atrás, la función mail() del servidor enviaba apenas el 20% de los mails de registro o recuperación de contraseña, para peor, arreglé esto cuando el concurso ya estaba iniciado. Por su parte el login por Facebook fallaba (cambian la API todo el tiempo), y no había otra forma de ingresar.

Solución: Primero que nada arreglé el de Facebook, me pareció más importante porque es más fácil para la gente loguearse con su cuenta de FB, están más acostumbrados y hasta muchos sólo usan FB para eso! es decir, ya no como red social sino porque es fácil de usar para ingresar a cualquier sitio. El resultado fue un éxito total porque MUCHOS usaron este método, la mayoría de los nuevos usuarios, y funcionó como una seda.

Solución 2: Google fue un martirio, la documentación no tiene NADA que ver con la realidad, encima todo lo hacen depender de frameworks que no uso en el blog, por lo que me costó mucho más y recién a último momento lo hice funcionar. Aun así no funciona perfecto, tiene problemitas con obtener los datos completos del usuario así que lo puse como opción B.

Solución 3: Los mails, qué problema! pero encontré la solución en Mailgun que no rebota, funciona bien y envía TODO. Usarlo es mucho más fácil que cualquier SMTP que siempre requieren instalar mil cosas para hacerlos funcionar (y no me funcionaba ninguno), es fácil, una API directa y valida todo. La verdad que me salió muy bien aunque hay que poner la tarjeta para que te lo activen más allá de modo de prueba.

Cacheo de listados



Ya el año pasado había creado un caché pero tenía sus bemoles, este año me dispuse a mejorarlo pero, mamita, sigue siendo un problema. Tengan en cuenta que todo el sitio tiene contenido cacheado pero cuando tenés un concurso donde cada minuto cambia el resultado, no vale cachear el mismo contenido durante una hora. No funciona, tiene que renovarse a cada rato!

Esto sumado al segundo problema: cada usuario ve cosas distintas porque su puntaje no es lo mismo que el del resto.

Normalmente cacheo a nivel página por lo que cada usuario debía generar su página y así guardaba esa versión durante 30 segundos para evitar el "acoso" de los amantes del F5. Pero tampoco fue lo más eficiente. Sólo el día mismo del concurso pensé en hacer cacheo por strings de texto, lo implementé al nivel de tabla de resultados que era la consulta más pesada, pero no fue perfecto.

El problema es que nunca le programé un panel de control, el caché se regeneraba luego de 30 segundos y la verdad que no debería ser así, debería generarse sólo cuando subí un resultado de una terna, así que no debería ser caché por tiempo sino por evento. Este será el cambio que le agregaré en el 2019.

El servidor se trabó un par de veces pero nunca cayó, es decir, tiró timeout la base de datos porque estaba al 100% pero no llegó a caer, lo que es bueno porque sino nos quedábamos sin concurso por un rato :D El VPS de Wiroos resisitó los embates, con los cambios que planeo para 2019 seguro que más todavía.

Lo bueno de todo esto es que pude hacerlo con un servidor con 2GB de RAM y 2 cores, un S.O. algo viejo y sin tener que recurrir a AWS o cualquier otro VPS costoso. Muchos terminan implementando soluciones carísimas a algo que, si lo cacheás bien, podés hacerlo con mucho menos. Lo importante es no depender tanto de MySQL a cada rato sino cuando se lo necesita.

Ganadores



Esta parte va evolucionando, primero agregué el DNI como "filtro" para aquellos que participan por deporte y los que participan en serio por el premio. El DNI sirve para filtrar un poco a los concurseros aunque si hacen participar a toda la familia más o menos es lo mismo. Pero da un contexto. Si me pongo en forro te demando el DNI a la entrega del premio y punto.

Por otro lado algo que ya me habían pedido varias veces, que el ganador fuera el que primero respondió. El listado del ranking, este año, ya está por orden de llegada, pero como no cambié oficialmente las reglas del juego no puedo forzar el resultado así que irá a sorteo como se debe. Son cuatro finalistas y justo fedexweb me pedía esto: si lo hago perdés porque fuiste el último en participar de los cuatro!! :D Más allá de eso el año que viene será por orden de llegada para privilegiar a los suicidas antes que a los concurseros de última hora.

Conclusiones



Lo interesante de hacer un concurso así en un sitio tan pequeño es que ponés a prueba al máximo el servidor y tu sistema, te encontrás con mil problemas que no habías calculado y, como soy un groncho programador, implemento cambios en vivo, cosa que nadie me permitiría hacer en uno más serio.

En una semana programé todos los fixes que hacían falta, algunos durante la misma votación, los de cacheo fueron en vivo, inclusive el envío de mails tuve que hacerlos el mismo día que lancé el concurso, por suerte fueron rápidas las soluciones y en una semana se sumaron 293 usuarios, 222 entrando por Facebook y 21 por Google. Además, claro, de los que ya estaban previamente.

Salió todo como esperaba aunque me hubiese venido muy bien crear una interfaz para administración ya que los resultados los cargué a mano en el MySQL :D así es, como buen nardo hice eso, es rápido para la mierda, pero para "restear" las páginas cacheadas tenía que hacerlo por consola, no es muy eficiente eso...

En síntesis, se puede hacer un concurso pero hay que tener MUCHAS cosas en cuenta para que tu servidor no se muera no por el volúmen de gente entrando (eso es fácil de contener) sino porque estás a cada rato calculando resultados y ESO es lo que voltea tu servidor, si todos calculan al mismo tiempo y usás la base de datos para hacerlo, estás frito. Lo importante, entonces, es una implementación más asíncrona, que se haga una sola vez el cálculo y no cuando el usuario lo pide. Ahí lo resolvés rapidísimo.

Si te gustó esta nota podés...
Invitame un café en cafecito.app


Otros posts que podrían llegar a gustarte...

Comentarios

  • Leandro Rotela     05/03/2018 - 11:52:10

    No puedo guardar mis resultados para el año que viene? :D

    Esto explicaría mucho lo de "el servidor no se lo banca" de ayer jaja sos Crack

  • Fabio Baccaglioni     05/03/2018 - 12:06:23

    Leandro Rotela dijo:

    No puedo guardar mis resultados para el año que viene? :D

    Esto explicaría mucho lo de "el servidor no se lo banca" de ayer jaja sos Crack


    estan los resultados de todos los concursos que hice para consultar!


    Esteban dijo:
    Excelente laburo Fabio.
    Un detalle que noto en los resultados: Veo que el nº de aciertos de algunos usuarios no se condicen con su detalle (Ej. Genny Costanti: https://www.fabio.com.ar/oscars2018/ver.php?id_usuario=3393).

    Pd: Qué malo que soy para estos concursos...


    si, tengo que chequear bien eso, medio raro que dos consultas den así cuando son a los mismos datos y no muy distintas...

  • Fabio Baccaglioni     05/03/2018 - 12:13:35

    Esteban dijo:

    Excelente laburo Fabio.
    Un detalle que noto en los resultados: Veo que el nº de aciertos de algunos usuarios no se condicen con su detalle (Ej. Genny Costanti: https://www.fabio.com.ar/oscars2018/ver.php?id_usuario=3393).

    Pd: Qué malo que soy para estos concursos...


    ah, ya me di cuenta, en realidad le está faltando una categoría que,p or alguna razón, no votó, así que está mostrando 19 y no 20, es un temita en el query, se puede arreglar rápido

  • Alejandro Hernan Perez     05/03/2018 - 12:46:44

    lo que hacemos en e-commerce es cachear todo y usar agujeros de cache para refrescar contenido.

    ejemplo, solo necesitarias obtener el si/no por cada usuario.

    capaz que la arquitectura de la base ayudaria tambien, como armaste?

  • Gustavo V     05/03/2018 - 13:19:47

    lo unico que vengo a decir es que por algun motivo no me tomo mi entrada :´(

    entre desde el celular...

    Me debes un celular.

  • Fabio Baccaglioni     05/03/2018 - 14:10:51

    Gustavo V dijo:

    lo unico que vengo a decir es que por algun motivo no me tomo mi entrada :´(

    entre desde el celular...

    Me debes un celular.


    shit happens! no te mostró nada en el preview antes de enviar?


    Alejandro Hernan Perez dijo:
    lo que hacemos en e-commerce es cachear todo y usar agujeros de cache para refrescar contenido.

    ejemplo, solo necesitarias obtener el si/no por cada usuario.

    capaz que la arquitectura de la base ayudaria tambien, como armaste?


    siempre se puede mejorar con la estructura de base de datos, yo porque no quería complicármela calculo al voleo, se puede hacer una matriz y que el cálculo no pase por DB sino que sea más directo y en memoria, si, hay mil métodos para acelerar

  • Nico     05/03/2018 - 14:37:05

    Para la proxima quiero radio buttons, que eso de votar en un listado! Mas bootstrap y menos queries! Ademas, como es eso que se te clava con 250 usuarios! Joder Fabio! Deja de hacer viajes a Europa y actualiza ese servidor Tilingo Menemista!

  • Fabio Baccaglioni     05/03/2018 - 15:02:45

    Nico dijo:

    Para la proxima quiero radio buttons, que eso de votar en un listado! Mas bootstrap y menos queries! Ademas, como es eso que se te clava con 250 usuarios! Joder Fabio! Deja de hacer viajes a Europa y actualiza ese servidor Tilingo Menemista!


    rata miserable, el blog no está armado con bootstrap, NO TENGO BOOTSTRAP ACÁ, si querés rediseñarme todo el blog con Bootstrap sos bienvenido y serás debidamente reconocido y hasta te regalaré un libro :D hace rato que quiero rediseñar pero me da paja el laburo que significa.

    Bastante que le hice botones legibles! Igual sí, el año que viene tocan radiobuttons ahí.

    No, el blog no se clava con 250 usuarios, se clava con 250 queries bestiales en una tabla si todos lo hacen a la vez. Para leer notas, por ejemplo, las cacheadas duran días (salvo que alguien comente), puede bancarse muchos más al mismo tiempo, pero el código de los Oscars lo hice en poco tiempo y nunca lo retoqué realmente :P así que lo que se dice optimizado... no lo está, tampoco los querys que son algo excesivos para un MySQL de webserver casi configurado default (si, tengo que empezar a tocarlo más, por suerte tengo acceso root en este server)

  • Jean Pierre     05/03/2018 - 15:04:43 Revisado: 05/03/2018 - 15:05:52

    Gustavo V dijo:

    lo unico que vengo a decir es que por algun motivo no me tomo mi entrada :´(

    entre desde el celular...

    Me debes un celular.


    Me paso lo mismo, viste que te avise por los mensajes de la página, pero cambiando el .php me lo tomó, con mensaje de que ya estoy participando y todo. Pude ver que opciones elegí, pero ahora no salí =(

    Muy bueno todo igual! Abrazo

  • Fabio Baccaglioni     05/03/2018 - 15:06:39

    Jean Pierre dijo:

    Gustavo V dijo:
    lo unico que vengo a decir es que por algun motivo no me tomo mi entrada :´(

    entre desde el celular...

    Me debes un celular.


    Me paso lo mismo, viste que te avise por los mensajes de la página, pero cambiando el .php me lo tomó, con mensajes y todo. Pude ver que opciones elegí, pero ahora no salí =(

    Muy bueno todo igual! Abrazo


    ese era otro problema, ahí te estaba cargando el .js que estaba en caché, le agregué un parámetro extra en el encabezado para que no lo tome de caché y funcionó. A algunos visitantes más asiduos les pasó eso así que apenas me enteré lo corregí. Es más un problema de browser pero es una cagada cuando te cachea un javascript que no esperabas que esté cacheado en browser.

  • fedexweb     05/03/2018 - 17:17:34 Revisado: 05/03/2018 - 17:20:14

    Es verdad, a partir del 3er año del concurso le rompí las bolas para que meta esa variable por que en los dos primeros años esperaba al segundo posterior de publicado el concurso para completar el formulario.
    También recuerdo que ante la negativa (por vago) de agregar esa variable Fabio me recomendó que esperara hasta último momento para completar el formulario, técnica que use estos dos últimos años.

    igual... SHOYA GANÉ

    <img src="https://giphy.com/embed/l3vRk6vO93jkRbk88">

    .

  • Mariano     05/03/2018 - 17:49:34

    Amo estos posts de experiencias técnicas. Sobre todo cuando son a puro huevo y sin depender de frameworks de moda.

    Solo de curiosidad, trabajas con algún tipo de repositorio o versionado, para tener backup y control de los cambios y cosas que tocas a lo McGiver? :D

    Con que cacheas el SQL? o solo cacheas el output del PHP para que no lo tenga que regenerar el servidor en cada petición?

  • Fabio Baccaglioni     05/03/2018 - 18:10:28

    Mariano dijo:

    Amo estos posts de experiencias técnicas. Sobre todo cuando son a puro huevo y sin depender de frameworks de moda.

    Solo de curiosidad, trabajas con algún tipo de repositorio o versionado, para tener backup y control de los cambios y cosas que tocas a lo McGiver? :D

    Con que cacheas el SQL? o solo cacheas el output del PHP para que no lo tenga que regenerar el servidor en cada petición?


    uso Git para el blog, podría ser bien cabeza pero ya hace años que uso Git para organizarme porque trabajo en 3 PCs distintas y de esta manera me controlo un poco mejor :P llevo bastante orden, eh!

    Lo que cacheo es el output de PHP porque el servidor donde estoy no me permite taaaaaanto control. Tengo que mantenerlo acotado, pero la que voy a hacer para el año que viene es cachear las consultas a la DB de cosas "calculables" para que sólo se haga una vez y no por cada usuario que aparece, eso reducirá el uso de CPU notablemente, sólo levanta la tabla de posiciones de un HTML sin vencimiento, sólo lo borro cuando hay cambios y así.

    Acepto sugerencias de cacheo de DB!

  • kevin gorisnic     05/03/2018 - 18:57:38

    Yo voto por sorteo para los que nunca ganan nada
    Este año estuve más cerca que los anteriores (anteriores fueron al azar y este busque en la otras pags)
    Y aun asi nada.
    Por lo pronto esta bien la pag.... no necesita siempre la abro en la compu.

  • Roberto Soto     06/03/2018 - 01:05:13

    Creo que soy el único que no aparece en el Ranking, pero no pasa nada, toda mi vida ha sido así.....

  • Hugo     06/03/2018 - 14:18:25

    Todo este lio es porque querés resultados al instante, verdad?

    Si dejás que todos voten, y cuando termina el Oscar cargás los resultados, tenés una página de resultados con una sola consulta por cada usuario que entra, que no va a ser simultáneo. (Por ahi es una boludez, arranqué programando en Clipper y dBase así que puedo tener conocimientos un poco obsoletos Guiño )

  • Emanuel     07/03/2018 - 12:10:56

    ¡Genial que compartís la experiencia!

    Para el asunto de logins/registros con redes sociales yo deje de renegar usando un js muy bueno: http://adodson.com/hello.js/

    Y para el envío de emails también uso uno muy parecido a mailgun (SMTP) pero más gratis :P se llama sparkpost.

    Saludos!

  • Ricardo Martin Suarez     07/03/2018 - 15:07:59

    Gustavo V dijo:

    lo unico que vengo a decir es que por algun motivo no me tomo mi entrada :´(

    entre desde el celular...

    Me debes un celular.


    Epa epa... Desde safari y después desde Chrome en un ipad tampoco tomó mis datos,
    Me loguee, cargue datos, en el resumen final el botón de aceptar "no recuerdo bien el texto del botón"
    Quedaba ahí sin refrescar..

    Fue el último día de concurso con el usuario del blog

  • Andrezgz     20/03/2018 - 22:30:09

    Me gustan los desafíos y viendo las restricciones con las que trabajás (servidor con 2GB de RAM y 2 cores, un S.O. algo viejo y sin tener que recurrir a AWS o cualquier otro VPS costoso) me sumo para proponer optimizaciones en las consultas sql, evaluando creación de índices, generando tablas temporales o campos con datos precalculados.

    Se podría analizar el peso del HTML generado y ver de reducirlo usando listas y clases css, en lugar de tablas y estilos inline. Esto además ayudaría a que la salida sea responsive y se ajuste mejor a la pantalla de un celular.

    Eso sí, no el mismo día del sorteo Guiño

  • Fernando Conti     23/03/2018 - 14:49:09

    Hola Fabio. Estaba leyendo que utilizás el servicio de la gente de Wiroos ... Estoy necesitando migrar el servidor de W2008 con unas maquinas virtualizadas a la nube y me gustarìa saber si me podès recomendar una par de proveedores confiables (es para una PYME) . En su momento habìan probado con Claro pero tenìa el problema que "no era doble vìa" (algo asì me dijeron, no manejo mucho el tema). Bàsicamente, necesitamos conectar con OpenVPN desde unas sucursales a un pfsense que y luego a una maquina con Red Hat dònde corre el sistema de facturaciòn y aparentemente con Claro no funcionaba .... La gente de Wiroos tienen una opciòn Gold pero son apenas unos 40 Gb y creo nos vamos a quedar cortos ... Perdòn por el off topic, pero estoy medio en bolas con esto. Gracias de antemano

  • Fabio Baccaglioni     24/03/2018 - 02:37:43

    Fernando Conti dijo:

    Hola Fabio. Estaba leyendo que utilizás el servicio de la gente de Wiroos ... Estoy necesitando migrar el servidor de W2008 con unas maquinas virtualizadas a la nube y me gustarìa saber si me podès recomendar una par de proveedores confiables (es para una PYME) . En su momento habìan probado con Claro pero tenìa el problema que &quot;no era doble vìa&quot; (algo asì me dijeron, no manejo mucho el tema). Bàsicamente, necesitamos conectar con OpenVPN desde unas sucursales a un pfsense que y luego a una maquina con Red Hat dònde corre el sistema de facturaciòn y aparentemente con Claro no funcionaba .... La gente de Wiroos tienen una opciòn Gold pero son apenas unos 40 Gb y creo nos vamos a quedar cortos ... Perdòn por el off topic, pero estoy medio en bolas con esto. Gracias de antemano


    por lo que contás necesitan infraestructura en serio, eso no recomiendo contratarlo al voleo por internet sino que sería mejor que hablen con algún comercial de Wiroos que pueda atender más específicamente su necesidad y poder darles lo que corresponde. Yo sólo uso servidores Linux así que no tengo tanto embrollo.

Deje su comentario:

Tranquilo, su email nunca será revelado.
La gente de bien tiene URL, no se olvide del http/https

Negrita Cursiva Imagen Enlace


Comentarios ofensivos o que no hagan al enriquecimiento del post serán borrados/editados por el administrador. Los comentarios son filtrados por ReCaptcha V3.