• Stars
    star
    310
  • Rank 134,926 (Top 3 %)
  • Language
    JavaScript
  • Created about 11 years ago
  • Updated over 9 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A sticky load balancer optimized for realtime apps

LoadBalancer.js

Join the chat at https://gitter.im/SocketCluster/loadbalancer

LoadBalancer.js is a sticky-session TCP load balancer which is optimized to work with realtime frameworks (with support for HTTP long polling fallbacks). It captures raw TCP connections from a specified port and forwards them to various targets (defined as host and port combinations). It chooses the appropriate target based on a hash of the client's IP address.

LoadBalancer.js was originally designed to work with SocketCluster (http://socketcluster.io) but it can work equally well with any other realtime framework.

Once a client establishes its first successful connection/request with a target, all subsequent connections/requests from that client will stick to that same target unless that target crashes or goes offline (or the session times out).

LoadBalancer.js handles target failures transparently. New connections can never fail so long as there is at least one active target - LoadBalancer.js will automatically rollback connections to bad targets behind the scenes without the client noticing.

Note that because targets are chosen based on each client's IP address, it is possible that a popular IP address could cause many sockets to be routed to the same target. See http://techcrunch.com/2007/01/01/wikipedia-bans-qatar/. This is only likely to be a problem if you are using relatively weak target servers that cannot handle more than a few thousand concurrent user. If your servers are sufficiently beefy, they should be able to handle slightly uneven loads. The beefier your target servers are, the better (so use more cores). On average, you can expect pretty good distribution between targets.

Note that large targets which have many active clients tend to lose clients as a faster rate than those who have fewer clients (it's a ratio). Since the incoming steam of clients to each target is a constant, you can expect targets to naturally regain equilibrium some time after an imbalance (such as one that could arise when a target crashes).

Install

npm install -g loadbalancer

Config

To run LoadBalancer.js, you just need to provide it with a config file (use --config some/path/config.json command line argument). Here is a sample config file showing the most basic options necessary:

{
  "sourcePort": 80,
  "targets": [
    {
      "host": "localhost",
      "port": 8000
    },
    {
      "host": "localhost",
      "port": 8001
    }
  ]
}

Here is a sample config file showing all available options:

{
  "sourcePort": 80,
  "balancerCount": 1,
  "targetDeactivationDuration": 60000,
  "sessionExpiry": 30000,
  "downgradeToUser": "someuser", 
  "stickiness": true,
  "balancerControllerPath": "../balancer.js",
  "targets": [
    {
      "host": "localhost",
      "port": 8000
    },
    {
      "host": "localhost",
      "port": 8001
    }
  ]
}

Options

  • sourcePort - The port that this load balancer will listen on.
  • balancerCount - [Optional - Defaults to available number of CPU cores] The number of load balancer processes to spawn.
  • targetDeactivationDuration - [Optional - Defaults to 60000] How long (in milliseconds) a target will be considered to be inactive after it fails to handle a connection before LoadBalancer will try again.
  • sessionExpiry - [Optional - Defaults to 30000] How long (in milliseconds) after a client severed all connections to target before expiring the session.
  • downgradeToUser - [Optional - Defaults to null] If you're launching LoadBalancer.js as root, you may wish to downgrade the permissions after launch for security purposes - This can be a Linux username or UID.
  • stickiness - [Optional - Defaults to true] Whether or not to use IP-based stickiness (instead of random target selection).
  • balancerControllerPath - [Optional - Defaults to null] The path to your balancerController script which you can use to block incoming connections before they are processed by LoadBalancer.js.
  • targets - An array of target servers to forward connections to (LoadBalancer.js will spread the load between them).

How to run

On Linux, make sure you have root privileges (sudo) - This is necessary if you want to bind to port 80. You may want to use the downgradeToUser option to downgrade to a different user after launch for extra security.

Start

loadbalancer start --config my/path/config.json

Stop

loadbalancer stop

Middleware

LoadBalancer.js does balancing at the TCP layer - This is great for performance and also means that it can work with HTTPS without having to supply it with a certificate. The downside is that target servers will not be able to see the clients' IP addresses (on a target server; req.connection.remoteAddress will in fact be the LoadBalancer's IP address and not the client's) - This means that if you want to do things like block a client based on their IP address, you will have to do it at the load balancer level. For this purpose, LoadBalancer.js lets you specify a balancerController script which allows you to define middleware which you can use to block incoming connections before they are handled by LoadBalancer.js.

Here is what the content of your balancerController script should look like:

module.exports.run = function (balancer) {
  balancer.addMiddleware(balancer.MIDDLEWARE_CONNECTION, function (socket, next) {
    // You can use whatever logic you want in order to decide whether or 
    // not to process this connection
    if (...) {
      // Allow connection to go through
      next();
    } else {
      // Block connection
      next('Blocked connection from client with IP: ' + socket.remoteAddress);
    }
  });
};

License

MIT

More Repositories

1

socketcluster

Highly scalable realtime pub/sub and RPC framework
JavaScript
6,151
star
2

sc-crud-sample

Sample real-time CRUD inventory tracking app built with SocketCluster
JavaScript
324
star
3

socketcluster-client

JavaScript client for SocketCluster
JavaScript
293
star
4

socketcluster-server

Minimal server module for SocketCluster
JavaScript
108
star
5

ndata

A deep key-value store for Node.js (server and client pair)
JavaScript
78
star
6

asyngular

Highly scalable realtime framework compatible with SocketCluster
JavaScript
77
star
7

client-drivers

List of SocketCluster clients
45
star
8

sc-redis

Redis adapter for SocketCluster
JavaScript
45
star
9

plugins

List of SocketCluster http://socketcluster.io plugins - Pull requests welcome.
33
star
10

sc-crud-rethink

Realtime CRUD data management layer/plugin for SocketCluster using RethinkDB as the database
JavaScript
33
star
11

sc-codec-min-bin

Minimal binary codec for SocketCluster based on MessagePack
JavaScript
24
star
12

socketcluster-client-ios

Native iOS client for SocketCluster
HTML
23
star
13

writable-consumable-stream

An async stream which can be iterated over using a for-await-of loop.
JavaScript
21
star
14

sc-stateless-presence

Plugin for checking user presence in SocketCluster. Optimized for front end use.
JavaScript
20
star
15

asyngular-server

Minimal server module for Asyngular
JavaScript
19
star
16

stream-demux

An alternative to using event listeners; improves control flow whilst helping to avoid memory leaks.
JavaScript
18
star
17

baasil-cli

A CLI tool for creating and deploying cloud native apps to Rancher + Kubernetes infrastructure
JavaScript
18
star
18

scc-state

Cluster state tracking and notification engine for SocketCluster clusters.
JavaScript
16
star
19

socketcluster-website

The SocketCluster website
JavaScript
14
star
20

sc-broker

Default broker client-server pair for SocketCluster
JavaScript
13
star
21

asyngular-client

JavaScript client for Asyngular
JavaScript
13
star
22

scc-broker

Server for the SC cluster - For horizontal scalability.
JavaScript
11
star
23

sc-rabbitmq

RabbitMQ adapter for SocketCluster
JavaScript
9
star
24

socketcluster-client-android

Native Android client for SocketCluster
HTML
8
star
25

iocluster

Realtime clustering engine for SocketCluster
JavaScript
7
star
26

async-stream-emitter

EventEmitter using async iterable streams
JavaScript
7
star
27

sc-auth

Auth module for SocketCluster
JavaScript
7
star
28

consumable-stream

Readable async iterable stream.
JavaScript
6
star
29

fleximap

A flexible hash map which supports working with deep, multidimensional keys.
JavaScript
5
star
30

eetase

EventEmitter to AsyncStreamEmitter converter.
JavaScript
4
star
31

sc-channel

Channels for SocketCluster
JavaScript
4
star
32

skeleton-rendezvous

Node.js module for performing fast rendezvous (HRW) hashing with skeleton - Can efficiently handle a large number of machines/sites.
JavaScript
4
star
33

socketcluster-client-edge

JavaScript
4
star
34

sc-stress-tests

Stress test client tool for SocketCluster
JavaScript
4
star
35

agc-broker

Server for the Asyngular cluster - For horizontal scalability.
JavaScript
2
star
36

sc-field

Field model component for Polymer and SocketCluster
HTML
2
star
37

made-with-sc

A list of projects using SC
2
star
38

sc-simple-broker

Simple broker engine for socketcluster-server
JavaScript
2
star
39

sc-broker-cluster

Broker cluster engine for SocketCluster
JavaScript
2
star
40

sc-errors

Error types for SocketCluster
JavaScript
2
star
41

ncom

A TCP socket pair which trigger a 'message' event only when the full message has been received.
JavaScript
2
star
42

sc-emitter

Emitter implementation (based on component-emitter) with support for Node.js error domains
JavaScript
2
star
43

sc-formatter

Module for serializing and unserializing SocketCluster messages
JavaScript
2
star
44

scc-broker-client

Client for SCC - For horizontal scalability.
JavaScript
2
star
45

sc-collection

SocketCluster collection component for the front end
JavaScript
2
star
46

sc-hot-reboot

Automatically reboot workers when code changes.
JavaScript
2
star
47

agc-state

Cluster state tracking and notification engine for Asyngular clusters.
JavaScript
1
star
48

ag-crud-sample

Sample real-time CRUD inventory tracking app built with Asyngular
JavaScript
1
star
49

sc-model

SocketCluster model component for the front end
JavaScript
1
star
50

sc-framework-health-check

Health check plugin for SocketCluster
JavaScript
1
star
51

scc-semver-report

This micromodule tries to find and report any incompatible components on all servers in your SocketCluster Cluster
JavaScript
1
star
52

ag-request

Asyngular request object
JavaScript
1
star
53

scc-integration-tests

Integration tests for SCC
JavaScript
1
star
54

expirymanager

An object for efficiently managing key expiries for in-memory databases
JavaScript
1
star
55

sc-cluster-state-client

Client for sc-cluster-state-server
1
star
56

ag-collection

SocketCluster collection component for the front end
JavaScript
1
star
57

ag-simple-broker

Simple broker engine for Asyngular
JavaScript
1
star