Foro de elhacker.net

Programación => Desarrollo Web => Mensaje iniciado por: Leguim en 13 Junio 2020, 22:26 pm



Título: [Pregunta]: ¿Una forma eficiente de hacer algo como esto?
Publicado por: Leguim en 13 Junio 2020, 22:26 pm
Básicamente tengo un sistema de versiones (v0.0.1, v.1.5.2, etcétera) que al agregar una quiero que se les envíe una notificación a todos los usuarios avisándoles, pero quiero hacerlo de la mejor forma posible para que el sistema no vaya lento o se "atasque"...

imaginemos una aplicación con 1 millón de usuarios...

Código
  1. $id_version = versiones::Agregar($x);
  2. notificaciones::Agregar($id_user, $id_version, 'versiones.php');
  3.  

se me ocurre hacer un for por medio de la cantidad de usuarios en total registrados, pero como dije un for con 1 millón de iteraciones no me parece una buena solución...

Código
  1. $id_version = versiones::Agregar($x);
  2.  
  3. for($i = 0; $i < count($usuarios_total); $i++)
  4. {
  5.        notificaciones::Agregar($id_user, $id_version, 'versiones.php');
  6. }
  7.  

Gracias!


Título: Re: [Pregunta]: ¿Una forma eficiente de hacer algo como esto?
Publicado por: MinusFour en 14 Junio 2020, 05:16 am
Pues lo ideal sería que usara concurrencia y paralelismo. Por ejemplo, podrías dividir la carga entre 4 diferentes procesos (250,000 registros por proceso) aunque ahí también va a depender del scheduler del sistema operativo.

Realmente, 1 millon de usuarios conectados al mismo tiempo a un solo servidor es bastante de por sí... Ni se diga que tienes que cargar 1 millon de registros. Imagina que son 250 bytes de información por registro, 1 millon de registros es cerca de 250MB en RAM.


Título: Re: [Pregunta]: ¿Una forma eficiente de hacer algo como esto?
Publicado por: Leguim en 14 Junio 2020, 10:44 am
Pues lo ideal sería que usara concurrencia y paralelismo. Por ejemplo, podrías dividir la carga entre 4 diferentes procesos (250,000 registros por proceso) aunque ahí también va a depender del scheduler del sistema operativo.

Realmente, 1 millon de usuarios conectados al mismo tiempo a un solo servidor es bastante de por sí... Ni se diga que tienes que cargar 1 millon de registros. Imagina que son 250 bytes de información por registro, 1 millon de registros es cerca de 250MB en RAM.

Estaba pensando algo parecido, pero lo dejé como una utopía... pero ahora que vos también lo comentas veré si no hago algo como eso.

No tengo del todo claro como debería hacerlo igualmente...


Título: Re: [Pregunta]: ¿Una forma eficiente de hacer algo como esto?
Publicado por: @XSStringManolo en 14 Junio 2020, 12:47 pm
Y hacer una pagina UltimaVersion.html y que los clientes le hagan GET? Si cambia haces un alert. Así cachean, cuando la modifiques cambias la url para evitar cachear y que se actualice:

<?php echo "<img src='example.com/UltimaVersion.html?'".$VERSION.">"; ?>

Mientras el valor de $VERSION no cambie, no recibirás peticiones más de una vez a ella porque se cachea el archivo.

Podrías meter dentro del hexadecimal de la imagen tu código javascript raw, fetchearlo y extraerlo. Es una técnica conocida para esconder exploits escritos en js.
https://blog.malwarebytes.com/threat-analysis/2019/12/new-evasion-techniques-found-in-web-skimmers/amp/


Título: Re: [Pregunta]: ¿Una forma eficiente de hacer algo como esto?
Publicado por: Leguim en 16 Junio 2020, 00:16 am
Estaba pensando en hacerlo con una consulta SQL,
no se si se podrá, que dicha consulta diga de agregar una notificación a todos los usuarios registros en lugar de usar un for en php, no se si será el mismo gasto la verdad...


Título: Re: [Pregunta]: ¿Una forma eficiente de hacer algo como esto?
Publicado por: [u]nsigned en 16 Junio 2020, 07:21 am
Estaba pensando en hacerlo con una consulta SQL,
no se si se podrá, que dicha consulta diga de agregar una notificación a todos los usuarios registros en lugar de usar un for en php, no se si será el mismo gasto la verdad...

Hacelo de forma inversa. Crea un tabla donde guardas las notificaciones a medida que los usuarios son notificados...

Así cuando un user entra, revisas en esa tabla si ya se notifico de X versión, si lo está no haces nada, si no lo esta, le mostras la notificación y luego creas el registro. entonces tu tabla no tendría un millón de registro de entrada, sino que se iría poblando a medida que van entrando los usuarios y solo se notificará a los usuarios activos.

Todo esto es en teoria, pero en un escenario real yo no usaría una base SQL para eso, mejor usaria una base como Redis que es mucho más eficiente y rápida y es el estándar de la industria para el realtime o cosas que necesiten mucha velocidad y el menor consumo manejando un volumen gigante de datos. Trabaja sobre la memoria ram, pero si tenes un sistema con un millón de usuarios supongo que tendrás un servidor con sobrados GB's de ram....  :silbar:

Otra forma que se me ocurre, un poco mas cutre, seria usar algun servicio de archivos estáticos con un cdn global, como Github.

Simplemente tendrías que crear un archivo json e ir metiendo ahí tus versiones. Entonces sería el cliente el que tendría que consultar el contenido de dicho archivo. Asi podes sacar toda la lógica de negocio de tu propia infraestructura, y a github un millón de peticiones no le hacen ni cosquillas...


Título: Re: [Pregunta]: ¿Una forma eficiente de hacer algo como esto?
Publicado por: @XSStringManolo en 16 Junio 2020, 22:53 pm
Probastes lo de github? Igual chapan con un 301


Título: Re: [Pregunta]: ¿Una forma eficiente de hacer algo como esto?
Publicado por: [u]nsigned en 17 Junio 2020, 05:43 am
Probastes lo de github? Igual chapan con un 301

Con la version 'raw' no debería tener problemas.

Código
  1. curl -H "Accept: application/json" https://raw.githubusercontent.com/LearnWebCode/json-example/master/animals-1.json


Título: Re: [Pregunta]: ¿Una forma eficiente de hacer algo como esto?
Publicado por: @XSStringManolo en 17 Junio 2020, 08:10 am
Con la version 'raw' no debería tener problemas.

Código
  1. curl -H "Accept: application/json" https://raw.githubusercontent.com/LearnWebCode/json-example/master/animals-1.json

Ostraaas, y se puede fetchear cross origen. Pensaba que hacían lo mismo que con los .js a pesar de ser json.

Código
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <body>
  6. <script>
  7. function PeticionGET(url, callback) {
  8.  var peticion = new XMLHttpRequest();
  9.  peticion.open("GET", url , true);
  10.  peticion.send();
  11.  peticion.onreadystatechange = function() {
  12.    if (peticion.readyState == 4) {
  13.      if (peticion.status == 0 || peticion.status == 200) {
  14.        callback(peticion.responseText);
  15.      }
  16.    }
  17.  }      
  18. }
  19.  
  20. PeticionGET("https://raw.githubusercontent.com/LearnWebCode/json-example/master/animals-1.json", function(respuesta) {
  21.  try {
  22.   document.write(JSON.stringify(respuesta));
  23.  } catch (err) {
  24.    alert(err);
  25.  }
  26. });
  27. </script>
  28. </body>
  29. </html>