Search code examples
configurationhaproxyround-robin

HAProxy - URL Based routing with load balancing - using listen and use-server


I need to configure HAProxy to forward requests of different paths to different backends, and some of the backends need to be load-balanced. So I've come across this question, and the solution provided there does work, but due to our conventions, I need to use listen and use-server instead of frontend and use_backend.

So right now I have something like this:

listen poq [url]:[port]
    acl has_cool_url path_beg -i /cool
    use-server cool if has_cool_url
    server cool [ip]:[port] check
    server default [ip]:[port] check

And I cannot use this:

listen poq [url]:[port]
    acl has_cool_url path_beg -i /cool
    use_backend cool if has_cool_url
    use_backend notcool if !has_cool_url

backend cool
    balance roundrobin
    server first [ip]:[port] check
    server second [ip]:[port] check

backend notcool
    server third [ip]:[port] check

Because our conventions tell us to define everything within the listen block.

So my question is: is there anything like this:

listen poq [url]:[port]
    acl has_cool_url path_beg -i /cool
    use-server {first, second} if has_cool_url
    server first [ip]:[port] check
    server second [ip]:[port] check
    server default [ip]:[port] check

Where first and second are load-balanced using round robin?


Solution

  • Your conventions are arbitrary and are limiting your functionality. A listen block is functionally similar to a single frontend and a backend block with the same name, and an implicit default_backend pointing from frontend to backend. listen blocks are intended to be used for simple configurations.

    The point of a backend is that all servers in the back-end provide the same service. use-server allows you to select exactly one server.

    The only thing you can do with listen is balance a single default set of servers, plus one or more individual servers, individually addressable using condition matches, but they can't be balanced.

    listen poq [url]:[port]
        acl has_warm_url path_beg -i /warm
        use-server warm-server if has_warm_url
        acl has_hot_url path_beg -i /hot
        use-server hot-server if has_hot_url
        server warm-server [ip]:[port] check weight 0
        server hot-server [ip]:[port] check weight 0
        server default1 [ip]:[port] check
        server default2 [ip]:[port] check
    

    In this configuration, /warm goes to warm-server, /hot goes to hot-server. These two servers are weighted 0 to prevent them from handling any other requests.

    Everything else is balanced between default1 and default2.

    This is all the flexibility you have with listen because HAProxy only does one set of balancing per backend, and, as noted above, a listen section is an implicit combination of the functionality of a matched set of frontend and backend.