Search code examples
routesload-balancinghaproxy

How to redirect to multiple servers sitting behind HAProxy which have different path begining


I have 3 servers which listen on following port ,

> 10.21.5.39:80    -->   api.something.com
> 10.21.4.234:80    -->   *.something.com
> 10.21.5.73:80     -->   coolapi.something.com
> 10.21.5.73:3002    -->   school.something.com

I am using a HAProxy server to redirect the traffic to these backends, i am using the following config on haproxy which doesn't seem to workout.

frontend api
       bind *:80
       acl url_api path_beg /api
       use_backend api-backend if url_api

frontend custui
       bind *:80
       acl url_custui path_beg *
       use_backend custui-backend if url_custui


frontend backoffice
       bind *:80
       acl url_backoffice path_beg /backoffice
       use_backend backoff-backend if url_backoffice

frontend partnerui
       bind *:80
       acl url_partnerui path_beg /partner
       use_backend partner-backend if url_partnerui


backend api-backend
    mode    http
    option  httpchk
    server  api01 10.21.5.39:80

backend custui-backend
    mode    http
    option  httpchk
    server  custui01 10.21.4.234:80

backend backoff-backend
    mode http
    option httpchk
    server backoff01 10.21.5.73:80


backend partner-backend
    mode http
    option httpchk
    server backoff01 10.21.5.73:3002

So the idea is to let HAProxy listen on 80 and then redirect to the backends listening on the specified port.. Please help


Solution

  • A couple of issues:

    • You have multiple frontends all listening on port 80; I would recommend having a single frontend and using ACLs to direct traffic to your backends. From the HAProxy documentation:

      There may be as many "use_backend" rules as desired. All of these rules are evaluated in their declaration order, and the first one which matches will assign the backend.

    • You provide option httpchk, but do not have any support for checks on your server lines; from the HAProxy documentation (1.5.18 specifically, but comparable for other versions)

      The port and interval are specified in the server configuration.

      I would recommend adding an interval (in ms), such as

      server  custui01 10.21.4.234:80 check inter 2000
      
    • You are specifying mode http and option httpchk in each backend; these can be combined in the defaults section and then overridden in a backend if necessary.

    • I like using hdr(host) to check for the HTTP request's URL, so I would rewrite acl url_api path_beg /api as acl url_api hdr(host) -m beg api., but that is down to personal preference

    Combining those recommendations with your listed requirements, here is an updated version of your configuration file:

    defaults
       mode    http
       option  httpchk
    
    frontend something.com
       bind *:80
    
       acl url_api path_beg /api
       use_backend api-backend if url_api
    
       acl url_backoffice path_beg /backoffice
       use_backend backoff-backend if url_backoffice
    
       acl url_partnerui path_beg /partner
       use_backend partner-backend if url_partnerui
    
       # Catches anything not covered by use_backend above
       default_backend custui-backend
    
    backend api-backend
        server  api01    10.21.5.39:80   check inter 2000
    
    backend backoff-backend
        server backoff01 10.21.5.73:80   check inter 2000
    
    backend partner-backend
        server backoff01 10.21.5.73:3002 check inter 2000
    
    backend custui-backend
        server  custui01 10.21.4.234:80  check inter 2000