“Proxying” muchas solicitudes HTTP con Node.js + Express 2

Estoy escribiendo proxy en Node.js + Express 2. El proxy debe:

  1. descifre la carga útil POST y emita una solicitud HTTP al servidor según el resultado;
  2. cifrar la respuesta del servidor y enviarla de vuelta al cliente.

La parte relacionada con el cifrado funciona bien. El problema que estoy enfrentando es el tiempo de espera. El proxy debe procesar las solicitudes en menos de 15 segundos. Y la mayoría de ellos son menos de 500ms, en realidad.

Problema aparece cuando aumento el número de solicitudes paralelas. La mayoría de las solicitudes se completan bien, pero algunas fallan después de 15 segundos + par de milis. ab -n5000 -c300 funciona bien, pero con una concurrencia de 500 falla para algunas solicitudes con tiempo de espera.

Solo podía especular, pero parece que ese problema es un orden de ejecución de devoluciones de llamada. Es posible que las solicitudes que vienen primero se cuelguen hasta ETIMEDOUT debido al enfoque del nodo en las últimas que aún se están procesando en un tiempo inferior a 500 ms.

PD: No hay problema con el servidor remoto. Estoy usando la solicitud de interacciones con ella.

actualizarse

La forma en que las cosas funcionan con algún código:

 function queryRemote(req, res) { var options = {}; // built based on req object (URI, body, authorization, etc.) request(options, function(err, httpResponse, body) { return err ? send500(req, res) : res.end(encrypt(body)); }); } app.use(myBodyParser); // reads hex string in payload // and calls next() on 'end' event app.post('/', [checkHeaders, // check Content-Type and Authorization headers authUser, // query DB and call next() parseRequest], // decrypt payload, parse JSON, call next() function(req, res) { req.socket.setTimeout(TIMEOUT); queryRemote(req, res); }); 

Mi problema es el siguiente: cuando ab emita, digamos, 20 POSTs a / , el manejador de rutas express se llama como miles de veces. Eso no siempre sucede, a veces 20 y solo 20 solicitudes se procesan de manera oportuna.

Por supuesto, ab no es un problema. Estoy 100% seguro de que solo 20 solicitudes enviadas por ab . Pero el controlador de ruta se llama varias veces.

No puedo encontrar razones para tal comportamiento, ¿algún consejo?

Puede echar un vistazo al módulo nodo-http-proxy y cómo maneja las conexiones. Asegúrate de no almacenar en búfer ningún dato y todo funciona por transmisión . Y debe intentar ver dónde está el tiempo dedicado a esas largas solicitudes. Intente instrumentar partes de su código con conosle.time y conosle.time y vea dónde se está demorando más tiempo. Si la mayor parte del tiempo se gasta en javascript, debe intentar crear un perfil. Básicamente, puede usar el perfilador v8, agregando la opción –prof a su comando de nodo. Lo que hace un v8.log y se puede procesar a través de una herramienta v8 que se encuentra en node-source-dir / deps / v8 / tools . Solo funciona si ha instalado el shell d8 a través de scons (scons d8). Puedes echar un vistazo a este artículo para ayudarte a seguir trabajando para que funcione.

También puede usar node-webkit-agent que usa herramientas de desarrollador de webkit para mostrar el resultado del generador de perfiles. También puedes echar un vistazo a mi tenedor con un poco de azúcar.

Si eso no funcionó, puedes intentar crear perfiles con dtrace (solo funciona en sistemas basados ​​en illumos como SmartOS).

Los tiempos de espera se debieron al uso de http.globalAgent que de manera predeterminada puede procesar hasta 5 solicitudes simultáneas a un host:port (lo cual no es suficiente en mi caso).

Miles de solicitudes (en lugar de decenas) fueron enviadas por ab (hecho aprobado por Wireshark bajo OS X; no puedo reproducir esto bajo Ubuntu dentro de Parallels).