Dienstag, 21. Juni 2011

Simple Loadbalancer with NodeJS HTTPS -> HTTP(S) Servers

Here I use NodeJS with a combination of the module node-http-proxy
To loadbalance requests to several server listening to https oder http

When you have installed NPM like this
curl http://npmjs.org/install.sh | sh
then you can install node-http-proxy by:
npm install http-proxy

 Now you can use this file proxy.js:

you can start the load-balancer like this:
node proxy.js

Sonntag, 19. Juni 2011

cluster Node.JS multi-core server manager capistrano tasks

cluster is a Node.JS multi-core server manager
more information you can find here: LearnBoost cluster website
and there github site: LearnBoost cluster github

Here I will describe how get some status information about an nodejs cluster from the LearnBoost Cluster manager via Capistrano

My LearnBoost Cluster file:

var cluster = require('cluster')
  , app = require('./mynodeapp');

  cluster('./mynodeapp')
    .set('workers', 2)
    .use(cluster.logger('log'))
    .use(cluster.debug())
    .use(cluster.stats({ connections: true, requests: true }))
    .use(cluster.pidfiles('pids'))
    .use(cluster.cli())
    .use(cluster.repl(8888, "%%NODEIPADDRESS%%"))
    .listen(3001, "%%NODEIPADDRESS%%");
please note that %%NODEIPADDRESS%% is my template which gets replaces with the internal ip address of this node.

To get an status overview of your deployed nodejs cluster I have a task like
desc "get node status"
task :node_status, :roles => [:app] do
  run "node #{current_path}/mynodeapp-cluster.js status"
end
this will use the cli from LearnBoost cluster

So when I hit: capistrano@server:~/git-repos/node-server$ cap production node_status

   [1.2.3.4] executing command
 ** [out :: 1.2.3.4]
 ** [out :: 1.2.3.4] worker 0 20841 alive
 ** [out :: 1.2.3.4] master 20836 alive
 ** [out :: 1.2.3.4] worker 1 20842 alive
 ** [out :: 1.2.3.4]
 ** [out :: 1.2.3.4] debug - exit
Another nice but more complicated task is the following which outputs stats about the nodes

desc "get node stats"
task :node_stats, :roles => [:app] do
  run "/usr/bin/expect #{current_path}/tools/#{application}_cluster_stats.expect"
end
to use this you need expect and telnet installed on your system which could be done with the following task
desc "install required debian packages for node_stats"
  task :install_debian_packages_for_node_status, roles => :app do
    run "#{try_sudo :as => 'root'} apt-get -qy install telnet expect"
  end
The expect file which is mentioned in the node_stats task looks like this:
 #!/usr/local/bin/expect.
spawn telnet %%NODEIPADDRESS%% 8888
expect "cluster>" { send "stats()\n" }
expect "cluster>"

replace template information inside deployed files when using capistrano

When you for example need some host specific information like a IP address in some files when you deploy something to multiple hosts via capistrano then you can use something like following:

This will output the IP-Address of interface eth1 from each host

desc "Print local ip address"
task :show_local_ip, :roles => [:app] do
  run "ifconfig eth1  | grep 'inet addr:'| cut -d: -f2 | awk '{ print $1}'"
end
You can extend it like this to replace a given template text inside a file with the IP from one interface

desc "replace local ip address"
task :replace_local_ip, :roles => [:app] do
  run "ifconfig eth1  | grep 'inet addr:'| cut -d: -f2 | awk '{ printf $1}' | xargs -0 -INEWIP perl -pi.bak -e 's/%%IPADDRESS%%/NEWIP/' #{current_releasse}/myconfig"
end
This  will replace %%IPADDRESS%% inside the myconfig file with the IP-Address of your Interface eth1