Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

477
Views
¿Cómo podemos establecer un tiempo de espera de solicitud total o descartar solicitudes en Node (al usar el módulo de clúster)?

Esta pregunta parece inocente porque podemos leer https://nodejs.org/api/http.html y detectar las siguientes opciones:

 server.requestTimeout = 1; server.keepAliveTimeout = 1; server.timeout = 1; server.setTimeout(1);

Fácil, ¿verdad? ¡No tan rapido!

Los tiempos de espera solo comienzan a contar una vez que el controlador de solicitudes acepta la solicitud en un proceso. Esto es importante porque hay dos lugares en los que las solicitudes pueden ponerse en cola en el nodo antes de llegar a ese punto:

  1. Si usamos el módulo de clúster, el proceso principal tiene una cola de solicitudes en memoria. Si los trabajadores están actualmente bloqueados (p. ej., haciendo renderizado de plantillas), las solicitudes se relajan aquí antes de que aparezcan en los trabajadores.
  2. Si no estamos utilizando el módulo de clúster y el proceso está bloqueado, las solicitudes pueden permanecer en un búfer de socket de nivel inferior

Parece que no puedo encontrar ninguna API integrada que nos permita establecer tiempos de espera que comiencen a contar cuando la solicitud llega al socket (lo que supongo que tiene sentido, ¿cómo sabría Node cuándo sucede esto?) Incluso si etiquetamos las solicitudes con un encabezado TIME_SENT o algo que nos permita eliminar solicitudes antiguas "manualmente" en un middleware, todavía tenemos que esperar un tiempo para que el proceso se desbloquee para hacerlo. Node no puede hacer esto por nosotros fuera de la banda.

Pero tal vez estoy equivocado? ¿Hay algo que me estoy perdiendo?

maxConexiones

También tenemos server.maxConnections : https://nodejs.org/api/net.html#net_server_maxconnections

Establezca esta propiedad para rechazar conexiones cuando el recuento de conexiones del servidor sea alto.

La razón por la que podemos querer establecer server.timeout en primer lugar es evitar que la cola de solicitudes se acumule durante las horas pico. ¡Configurar server.maxConnections también debería lograr esto!

Con un solo proceso, esta configuración hace casi lo que queremos.

Usando un servidor hello world (https://i.fluffy.cc/FvGQHxMfKGScFcSkJBw1MRVL7x7hplB3.html) , podemos ejecutar:

 for i in `seq 1 10`; do echo "${i}: "; curl localhost:8000 &; done

Aquí hay una secuencia de comandos que hace lo mismo que el bucle curl, pero con una salida más elegante:

 $ node test.js ┌─────────┬─────────┬─────────────────────────────────────────────────────┬─────────────┐ │ (index) │ success │ output │ timeTaken │ ├─────────┼─────────┼─────────────────────────────────────────────────────┼─────────────┤ │ 0 │ true │ '[pid: 23628] Request seen at: 1615192813' │ 1015.566695 │ │ 1 │ true │ '[pid: 23628] Request seen at: 1615192814' │ 2012.38064 │ │ 2 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1011.044642 │ │ 3 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1009.696098 │ │ 4 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1007.128426 │ │ 5 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1005.725304 │ │ 6 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1004.444839 │ │ 7 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1003.128797 │ │ 8 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1001.813047 │ │ 9 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1000.523041 │ └─────────┴─────────┴─────────────────────────────────────────────────────┴─────────────┘ Results: 2 / 10 requests succeeded

... y de hecho vemos el valor respetado!

Sin embargo, tenga en cuenta que tenemos que esperar a que se produzca la operación de bloqueo para que el nodo finalice las otras solicitudes. Solo recibimos recv después de ~ 1 segundo, en lugar de inmediatamente. No es lo ideal, pero no estoy seguro de qué más podríamos hacer.

(A menos que me esté perdiendo algo, ¿y hay una forma mágica fuera de banda para eliminar las solicitudes?)

Módulo de clúster

¿Y si estamos obligados a usar el módulo de clúster de nodos? Tal vez estemos usando una biblioteca (por ejemplo, hipernova )

Aquí hay un servidor hello world agrupado .

Ahora tenemos un proceso principal y 2 trabajadores cada uno con server.maxConnections = 1

Cuando ejecutamos el mismo conjunto de solicitudes paralelas, vemos el siguiente resultado:

 $ node test.js ┌─────────┬─────────┬─────────────────────────────────────────────────────┬─────────────┐ │ (index) │ success │ output │ timeTaken │ ├─────────┼─────────┼─────────────────────────────────────────────────────┼─────────────┤ │ 0 │ true │ '[pid: 6246] Request seen at: 1615162602' │ 1012.041639 │ │ 1 │ true │ '[pid: 6247] Request seen at: 1615162602' │ 1009.773912 │ │ 2 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1006.635283 │ │ 3 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1006.259198 │ │ 4 │ true │ '[pid: 6246] Request seen at: 1615162603' │ 2001.560547 │ │ 5 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1001.442373 │ │ 6 │ true │ '[pid: 6247] Request seen at: 1615162603' │ 2001.787769 │ │ 7 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1998.214606 │ │ 8 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 1999.735996 │ │ 9 │ false │ 'curl: (56) Recv failure: Connection reset by peer' │ 998.881888 │ └─────────┴─────────┴─────────────────────────────────────────────────────┴─────────────┘ Results: 4 / 10 requests succeeded

Aquí hay una visualización de esta línea de tiempo de solicitud:

solicitud de cronograma

¡Esperar! Si tenemos 2 trabajadores, cada uno con server.maxConnection = 1 , si todo funcionó igual, solo deberíamos procesar 2 solicitudes en total... ¡pero vemos que se procesan 4 solicitudes! ¡mmm!

Y a diferencia de la versión de un solo trabajador, tenemos que esperar ~2 segundos en algunos casos para que se eliminen las solicitudes al final de la cola. ¿Por qué? Idealmente, se dejarían caer de manera similar en 1s.

No estoy seguro de por qué vemos [request] [drop] [drop] [request] [drop] en lugar de:

  • [request] [request] [drop] [drop] [drop] o incluso;
  • [request] [drop] [drop] [drop] [request]

¿Alguna idea de lo que está pasando aquí?

(FWIW, aquí hay una pequeña inmersión profunda en cómo las colas de solicitudes parecen funcionar en un nivel inferior en el módulo de clúster)

Abordar el problema XY

  • "¿Por qué necesitarías querer hacer esto? ¡Simplemente elimine manualmente las solicitudes en función de un encabezado de presupuesto de solicitud!"

    Sí, hacer esto de todos modos, pero el cliente/malla que llama aún no debería tener que querer esperar un tiempo de espera completo, por lo que podría volver a intentar su solicitud a un host diferente

  • "¿Por qué tus trabajadores están bloqueados? ¡No bloquees el trabajo en el nodo!"

    Cuando se renderiza del lado del servidor, ReactDOM.renderToString() es síncrono :P

Este es el comportamiento esperado

No hay tanto misterio sobre por qué sucede esto, sino más bien sobre cómo podemos trabajar en torno a esto para ser un "buen ciudadano de malla".

¿Quizás una nueva API expuesta a través de Node, por lo que el proceso principal en el módulo de clúster tiene acceso a la cola de solicitudes?

Las soluciones actuales en las que puedo pensar implican configurar un proxy para negociar manualmente las solicitudes y administrar la cola de solicitudes, pero esto es asqueroso y subvierte algunas de las ventajas de usar el módulo de clúster en primer lugar.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Puede consultar la respuesta dada aquí , que describe aproximadamente lo que está tratando de lograr (creo), en cuanto a acceder a las conexiones desde el proceso maestro. Se basa en alguna configuración manual del servidor http en el proceso maestro, lo que permite una distribución de solicitudes más personalizada (o en su caso, un manejo de carga más personalizado).

Esa respuesta no proporciona detalles sobre el uso de maxConnections o requestTimeout para manejar la carga y/o fallar antes, pero:

  • si establece esos valores (maxConnections/requestTimeout) en el servidor http/s del proceso maestro (donde en teoría no está ejecutando ninguna tarea de bloqueo/ejecución prolongada)
  • y si puede realizar un seguimiento del estado de cada trabajador (y sus solicitudes en curso) desde el maestro

es posible que pueda lograr el comportamiento que está buscando. Suponiendo que la sugerencia anterior funcione, no puedo hablar sobre el rendimiento, ya que la lógica y el paso de mensajes pueden imponer un nivel inaceptable de procesamiento adicional necesario en cada solicitud, pero eso es especular.

Si eso no funciona, puede ser posible modificar el enfoque, pero vaya a un nivel más bajo (tal vez los módulos tcp o net) y vea si alguno de ellos expone un mayor nivel de control que le permitiría gestionar las solicitudes entrantes de la manera que desee. En el peor de los casos, la idea del proxy parece que funcionaría en un apuro.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!