rlb

Redirecting Load Balancer

MIT License

Stars
40
Committers
4

RLB - Redirecting Load Balancer

This service redirects incoming GET and HEAD requests (with 302) to the upstream servers. Servers picked up randomly, unhealthy boxes excluded dynamically.

Note: This is not a replacement for reverse proxy. All it does is HTTP redirect, not the real network proxying.

To visualise the redirected content popularity statistics, you can use rlb-stats.

Install

  1. Copy provided docker-compose.yml
  2. Make rlb.yml config for your service(s) (see rlb-sample.yml below in Config file format section).
  3. Start container with docker-compose up -d

This will start rlb on port :7070 by default and requests like http://host/api/v1/jump/service1?url=/files/blah.mp3 will be redirected to the one of upstreams.

API

  • GET|HEAD /api/v1/jump/<service>?url=/blah/blah2.mp3 – returns 302 redirect to destination server
  • GET|HEAD /<service>?url=/blah/blah2.mp3 – same as above

Failback support (optional)

This allow to check the upstreams health for the requested resource and failback to a predefined servers if request fails. failback defined in the config file and in case if non-empty will add an additional HEAD request to the final URL. If request returns 200, the request will be passed to the upstream, if not - the result will be assembled from the failback + resource. I.e. if failback is http://failback.com/ and resource is /files/blah.mp3 then the final URL will be http://failback.com/files/blah.mp3.

Config file format

# top level services
service1:
    n1: # node id
        server: http://n1.radio-t.com     # base url 
        ping: /rtfiles/rt_podcast480.mp3  # ping url to check node's health
        method: HEAD                      # ping method, uses HEAD if nothing defined
        weight: 1                         # relative weight of the node [1..n]   

    n2:
        server: http://n2.radio-t.com
        ping: /rtfiles/rt_podcast480.mp3
        method: HEAD
        weight: 1

    n3:
        server: http://n3.radio-t.com
        ping: /rtfiles/rt_podcast480.mp3
        method: HEAD
        weight: 5                         # this node will get 5x hits comparing to n1 and n2 

service2:
    n1:
        server: http://n1.radio-t.com
        ping: /rtfiles/rt_podcast480.mp3
        method: GET
        weight: 1

    n2:
        server: http://n2.radio-t.com
        ping: /rtfiles/rt_podcast480.mp3
        method: GET
        weight: 3

    n3:
        server: http://n3.radio-t.com
        ping: /rtfiles/rt_podcast480.mp3
        method: GET
        weight: 1

failback: http://archives.radio-t.com/media

Stats

RLB does not implement any statistics internally but supports external service for requests like this:

	type LogRecord struct {
		ID       string    `json:"id,omitempty"` // uniuque id
		FromIP   string    `json:"from_ip"`      // source ip
		TS       time.Time `json:"ts,omitempty"` // timestamp
		Fname    string    `json:"file_name"`    // requested file name
		Servcie  string	   `json:"service"`      // requested service
		DestHost string    `json:"dest"`         // picked destination node
	}

If stats url defined in command line or environment, each redirect will also hit stats url (POST) with LogRecord in body.

Parameters

Usage:
  main [OPTIONS]

Application Options:
  -p, --port=    port (default: 7070) [$PORT]
  -c, --conf=    configuration file (default: rlb.yml) [$CONF]
  -r, --refresh= refresh interval (default: 30) [$REFRESH]
  -t, --timeout= HEAD/GET timeouts (default: 5) [$TIMEOUT]
  -s, --stats=   stats url [$STATS]
      --dbg      debug mode [$DEBUG]

Status

RLB runs in production for several years and serves downloads from radio-t