3

I have two independent applications A and B. Each application uses blue/green deployments via blue/green AWS load balancers registered in a HAProxy backend using weighted routing.

I have the requirement to route traffic across both applications (backends) based on a weight, for example routing 90% of traffic to backend A and the remaining 10% to backend B.

Is it possible to set up a frontend in HAproxy that distributes traffic across multiple backends in the above way?

I considered putting all ALBs for both applications in a single backend but it then makes independently shifting traffic between blue/green of each application more complex.

Another option is to set up internal DNS for A backend and B backend and then the default backend can route between that but ideally I would avoid going "out" of HAProxy just to route back in.

Ben
  • 243
  • 3
  • 10

1 Answers1

3

To selectively route identical requests to different "backends" (as defined by HAProxy -- server groups) you need some criterion that you can calculate in the frontend for each request -- and then use_backend when it's true (or false, as the case may be).

For example, the rand() fetch returns a random integer (not random in the cryptographic sense but random enough for this purpose) and the mod() converter returns the result of modulo division, so if we want approximately 1:10 requests to go to backend bbb and the rest to go to backend aaa then we could do something like this:

frontend main
    mode http
    ...
    use_backend bbb if { rand(),mod(10) -m int 0 }
    default_backend aaa

Converters like mod() are preceded by their input so the output of rand() is the first input of mod() and the output of mod() is compared as an integer -m int against 0. If the random integer is evenly divisible by 10 then the expression is true and backend bbb is used.

You might further improve this by verifying that bbb has at least one healthy server before deciding to send it requests, by using the nbsrv() fetch to insure that the number of healthy servers in bbb is greater than 0.

use_backend bbb if { rand(),mod(10) -m int 0 } { nbsrv(bbb) gt 0 }

Note that the config parser requires each { and } to have whitespace before and after except at the end of a line.

Michael - sqlbot
  • 22,658
  • 2
  • 63
  • 86