airbnb/synapse — pull request #30 by memory (2013-11-30 05:52:47+00:00)
Title: proposal: shared frontend stanzas in haproxy sections

Assuming that your underlying architecture makes no breaking assumptions,
there is no need to dedicate a port to each service: services which need to
be co-located on a single IP address can, for instance, share some sort of
app container and route based on host or path names.

While haproxy can route on host headers, synapse currently assumes a 1:1
frontend:backend ratio. But what we want here is a single frontend mapping
to multiple backends based on acl rules. So herein, a simple stab at it:
if there is a "shared_frontend" key in the root haproxy config, we create
a "shared-frontend" frontend, read in any configuration lines, and then as
we iterate over the services, pluck out any shared_frontend lines like so:

{ "haproxy": {
"shared_frontend": [
"bind 127.0.0.1:8081"
],
"global": [
"daemon",
"stats socket /var/run/haproxy.sock"
],
"defaults": [
"log global",
],
},
"services": {
"service1": {
"haproxy": {
"server_options": "check inter 2s rise 3 fall 2",
"backend": [
"mode http"
],
"shared_frontend": [
"acl is_service1 hdr_dom(host) -i service1.lb",
"use_backend service1 if is_service1"
]
}
},
"service2": {
"haproxy": {
"server_options": "check inter 2s rise 3 fall 2",
"backend": [
"mode http"
],
"shared_frontend": [
"acl is_service2 hdr_dom(host) -i service2.lb",
"use_backend service2 if is_service2"
]
}
}
}
}

...produces a FE/BE config like this:

frontend service1
bind localhost:8086
default_backend service1

backend service1
mode http
server host1_service1:8101_20d8a0f6 10.73.132.39:8101 check inter 2s rise 3 fall 2
server host1_service1:8101_4f48153f 10.181.203.244:8101 check inter 2s rise 3 fall 2

backend service2
mode http
server host1_service2:8101_6f0a9d02 10.60.12.9:8101 check inter 2s rise 3 fall 2
server host2_service2:8101_f3518f4f 10.81.23.44:8101 check inter 2s rise 3 fall 2

frontend shared-frontend
bind 127.0.0.1:8081
acl is_service1 hdr_dom(host) -i service1.lb
use_backend service1 if is_service1
acl is_service2 hdr_dom(host) -i service2.lb
use_backend service2 if is_service2