The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Web proxy in node.js for high availability

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Paul Gross

Posts: 152
Nickname: pgross
Registered: Sep, 2007

Paul Gross is a software developer for ThoughtWorks.
Web proxy in node.js for high availability Posted: Jan 31, 2010 11:00 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Paul Gross.
Original Post: Web proxy in node.js for high availability
Feed Title: Paul Gross's Blog - Home
Feed URL: http://feeds.feedburner.com/pgrs
Feed Description: Posts mainly about ruby on rails.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Paul Gross
Latest Posts From Paul Gross's Blog - Home

Advertisement

I’ve been thinking about high availability websites lately. In particular, I want sites that can be upgraded (including database migrations or even infrastructure changes) without downtime.

I’ve also been playing with node.js lately, and I decided to spike out a web proxy that would sit between users and the actual website (eg, a rails app). When performing upgrades, the proxy would hold users connections and wait. Once the upgrade was done, the proxy would forward requests as usual. Users would see an extra long request, but as long as the upgrade was short (eg, less than a minute), the user should not know the site was down.

This type of proxy server seems like a good fit with node. Node’s event model means that there will be very little overhead when holding connections. There are no threads stacking up and waiting. Since everything is non-blocking, this server should scale well.

Here is a very simple version of the code:


var posix = require('posix'),
      sys = require('sys'),
     http = require('http');

http.createServer(function (req, res) {
  checkBalanceFile(req, res);
}).listen(8000);

function checkBalanceFile(req, res) {
  var promise = posix.stat("balance");
  promise.addCallback(function () {
    passThroughOriginalRequest(req, res);
  });
  promise.addErrback(function () {
    setTimeout(function() {checkBalanceFile(req, res)}, 1000);
  });
}

function passThroughOriginalRequest(req, res) {
  var request = http.createClient(2000, "localhost").request("GET", req.url, {});
  request.finish(function (response) {
    res.sendHeader(response.statusCode, response.headers);
    response.addListener("body", function (chunk) {
      res.sendBody(chunk);
    });
    response.addListener("complete", function () {
      res.finish();
    });
  });
}

sys.puts('Server running at http://127.0.0.1:8000/');

Here is a gist if anyone would like to fork.

Basically, I use http.createServer to create a web server on port 8000. On incoming requests, I call checkBalanceFile. This method will try to stat a local file called balance. If it finds it, it will call passThroughOriginalRequest, which forwards the request to another web server on port 2000. If the balance file does not exist, I use setTimeout to call checkBalanceFile again in one second.

With a proxy server like this, the main application can be upgraded by removing the balance file. While the file is missing, the node web server will hold all of the connections and check every second for the reappearance of the balance file. Once it comes back, all requests will be forwarded along and then streamed back to the user.

Currently, this spike only works with GET requests and does not pass any headers through, since I wanted to keep the code simple.

Read: Web proxy in node.js for high availability

Topic: Styling Flex Applications Previous Topic   Next Topic Topic: Subdomains in development using ghost

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use