0

What i have

  • incoming single http request with ~10mb of data (i get hundreds of them in seconds)
  • couple of servers. loadBalancer, server-1, server-2, ... availableServer

What i am currently doing
1- loadBalancer gets request. Downloads data. Choose server. Send request to availableServer
2- Processed data send back to loadBalancer
4- Load balancer send the result to user.

Problem
loadBalancer is downloading, uploading and handling big data as extra. Which slow downs the response time for user.

What i want
1 - Http/https request will come to my loadBalancer server
2 - loadBalancer choose destination server and redirect the request without downloading big data in request body.
3 - Main server will process the data and return the result to the user.

My Question
How to redirect the request without downloading data in body? Or what technique should i use to overwhelm this situation. I just want loadBalancer to do a gentle touch to request to adjust it in the right direction.

Possible but unwanted solution
User can simply call

var bestServerUrl = get('loadBalancer/getAvailableServerUrl')
var result = post('bestserverUrl/processData',bigData)

But this way is unwanted. Becomes more complex for user. User might only use one server url. etc... It should be handled by me.

  • Does https://stackoverflow.com/questions/72978088/http-proxy-middleware-dynamic-target answer your question? Your load balancer behaves like a proxy with dynamic target. – Heiko Theißen Jul 20 '22 at 18:23
  • @HeikoTheißen as you suggested i have tried `http-proxy-middleware` in my `loadBalancer`. Exactly the same codes in suggested link. But request has big data in body again. So `loadBalancer` is fully downloaded the big data before redirecting it. Am i missing a point? – Çağrı Eroğlu Jul 20 '22 at 19:31
  • Where exactly did you observe the big data in the body of the request? Can you share the line of code that contains the variable containing the big data? See also my answer. – Heiko Theißen Jul 21 '22 at 07:43

1 Answers1

0

See http-proxy-middleware, dynamic target. Your load balancer behaves like a proxy with dynamic target.

As the following code demonstrates, the load balancer (on port 8080) feeds the request body through to the available server (on port 8081) chunk by chunk, as it receives them. (The code simulates two chunks sent with a one second interval between them.)

express()
.use(function(req, res) {
  req.on("data", function(data) {
    console.log("Received " + data);
  });
})
.listen(8081, function() {
  express()
  .use(createProxyMiddleware({target: "http://localhost:8081"}))
  .listen(8080, function() {
    var req = http.request("http://localhost:8080", {method: "POST"});
    req.write("A");
    console.log("Sent A");
    setTimeout(function() {
      req.write("B");
      console.log("Sent B");
    }, 1000);
  });
});

The load balancer does not fully download the big data before redirecting it. It opens an outgoing request to the available server and pipes the incoming request into that outgoing request. How big the chunks of transferred data are depends on the buffering settings in Node.js. In the end the entire big data passes through the load balancer, but it need not keep more than one chunk at a time in its memory.

Heiko Theißen
  • 12,807
  • 2
  • 7
  • 31
  • I tried. Seems like it is working. Can you explain how/why this is working?. As far as i understand first TCP packet comes in 64Kb. Then request is redirected to destination server. `loadBalancer` is only downloading first chunk. Not rest of the data. Am i right?. I can't 100% sure because `req.on('data')` event is not triggering at all in `loadBalancer` when we write `http-proxy-middleware` as first middleware. – Çağrı Eroğlu Jul 21 '22 at 12:28