How to Implement Host-Based Routing in HAProxy for Multiple Backend Services


2 views

Your existing HAProxy configuration shows a basic load balancing setup with round-robin distribution across multiple app servers (8081-8084 ports). This works well for generic traffic distribution, but lacks host-based routing capabilities needed for more complex deployments.

HAProxy provides powerful ACL (Access Control List) capabilities for host-based routing. The key components you'll need are:

frontend http-in
  bind *:80
  acl host_myspecial hdr(host) -i myspecialtopleveldomain.com
  use_backend apache_backend if host_myspecial
  default_backend app_servers

Here's how to modify your config to handle both scenarios:

global
  log 127.0.0.1 local0
  log 127.0.0.1 local1 notice
  maxconn 4096

defaults
  log global
  mode http
  option httplog
  option dontlognull
  retries 3
  redispatch
  maxconn 2000
  timeout connect 5000
  timeout client 50000
  timeout server 50000

frontend http-in
  bind *:80
  acl is_special hdr(host) -i myspecialtopleveldomain.com
  use_backend apache_backend if is_special
  default_backend app_servers

backend apache_backend
  server apache1 example.com:8001 check

backend app_servers
  balance roundrobin
  option httpclose
  option forwardfor
  server inst1 0.0.0.0:8081 check inter 2000 fall 3
  server inst2 0.0.0.0:8082 check inter 2000 fall 3
  server inst3 0.0.0.0:8083 check inter 2000 fall 3
  server inst4 0.0.0.0:8084 check inter 2000 fall 3

For production environments, consider these enhancements:

# Multiple host matching
acl host_blog hdr(host) -i blog.example.com
acl host_api hdr(host) -i api.example.com

# Path-based routing within same host
acl path_static path_beg /static/
acl path_api path_beg /api/v2/

The updated configuration separates frontend and backend declarations for better readability and maintainability. The ACL rules provide flexibility for future expansion, while the timeout values ensure stable connections under heavy load.


Let's first examine the existing HAProxy configuration that balances traffic across multiple application servers:

global
  log 127.0.0.1 local0
  log 127.0.0.1 local1 notice
  maxconn 4096
  debug

defaults
  log global
  mode  http
  option  httplog
  option  dontlognull
  retries 3
  redispatch
  maxconn 2000
  contimeout  5000
  clitimeout  50000
  srvtimeout  50000

listen appservers 0.0.0.0:80
  mode http
  balance roundrobin
  option httpclose
  option forwardfor
  server  inst1 0.0.0.0:8081 cookie server01 check inter 2000 fall  3
  server  inst2 0.0.0.0:8082 cookie server02 check inter 2000 fall  3
  server  inst3 0.0.0.0:8083 cookie server01 check inter 2000 fall  3
  server  inst4 0.0.0.0:8084 cookie server02 check inter 2000 fall  3
  capture cookie vgnvisitor= len 32

To implement hostname-based routing, we'll need to modify the configuration to use HAProxy's ACL (Access Control List) feature. Here's how to route traffic for myspecialtopleveldomain.com to example.com:8001 while maintaining the existing load balancing:

frontend http-in
  bind *:80
  mode http
  
  # Define ACL for hostname matching
  acl host_myspecial hdr(host) -i myspecialtopleveldomain.com
  
  # Route to Apache if host matches
  use_backend apache_backend if host_myspecial
  
  # Default to app servers
  default_backend app_servers

backend apache_backend
  mode http
  server apache1 example.com:8001 check

backend app_servers
  mode http
  balance roundrobin
  option httpclose
  option forwardfor
  server inst1 0.0.0.0:8081 cookie server01 check inter 2000 fall 3
  server inst2 0.0.0.0:8082 cookie server02 check inter 2000 fall 3
  server inst3 0.0.0.0:8083 cookie server01 check inter 2000 fall 3
  server inst4 0.0.0.0:8084 cookie server02 check inter 2000 fall 3
  capture cookie vgnvisitor= len 32

The modified configuration introduces several important concepts:

  • Frontend declaration: Defines the entry point for incoming traffic
  • ACL rules: Conditionally match requests based on host header
  • Backend selection: Routes traffic based on ACL evaluation
  • Multiple backends: Maintains separation between different server groups

For more complex routing needs, you can extend this pattern:

frontend http-in
  bind *:80
  mode http
  
  acl host_blog hdr(host) -i blog.example.com
  acl host_api hdr(host) -i api.example.com
  acl host_static hdr(host) -i static.example.com
  
  use_backend blog_servers if host_blog
  use_backend api_servers if host_api
  use_backend static_servers if host_static
  
  default_backend app_servers

When implementing hostname-based routing:

  • Keep ACL rules simple and minimal for best performance
  • Consider using HAProxy's pattern matching for complex hostname patterns
  • Monitor performance impact when adding many ACL rules
  • For high-traffic sites, consider separating frontend and backend processes

If you need to handle HTTPS traffic:

frontend https-in
  bind *:443 ssl crt /etc/ssl/certs/mydomain.pem
  mode http
  
  acl host_myspecial hdr(host) -i myspecialtopleveldomain.com
  use_backend apache_backend if host_myspecial
  default_backend app_servers

Remember to configure SSL certificates for all domains you'll be routing.

After making configuration changes:

  1. Validate configuration syntax: haproxy -f /etc/haproxy/haproxy.cfg -c
  2. Test with curl: curl -H "Host: myspecialtopleveldomain.com" http://your-haproxy-ip
  3. Check HAProxy stats for routing behavior
  4. Monitor logs for any routing errors