简单示例

将请求简单地代理到下一台服务器

  1. listen http-server
  2. bind :80
  3. mode http
  4. default_backend backend-default
  5. backend backend-default
  6. mode http
  7. server server1 192.168.0.10:80

另外一种写法

  1. listen http-server
  2. bind :80
  3. mode http
  4. server default 192.168.0.10:80

虚拟主机

Haproxy 支持根据域名将请求转发到不同的服务器,使用后端服务器组能实现负载均衡。

  1. listen http-server
  2. bind :80
  3. mode http
  4. acl is-foo hdr_dom(host) -i foo.com
  5. acl is-bar hdr_dom(host) -i bar.com
  6. use_backend backend-foo if is-foo
  7. use_backend backend-bar if is-bar
  8. default_backend backend-no-match
  9. backend backend-foo
  10. mode http
  11. server server1 192.168.0.10:80
  12. server server2 192.168.0.11:80
  13. backend backend-bar
  14. mode http
  15. server server1 192.168.0.20:80
  16. server server2 192.168.0.20:80
  17. backend backend-no-match
  18. http-request deny deny_status 400

如果没有设置 default_backend ,当找不到匹配的路由时会报 503 Service Unavailable。
以上域名判断也可以简写为:

  1. # 完整写法
  2. acl is-foo hdr_dom(host) -i foo.com
  3. use_backend backend-foo if is-foo
  4. # 合并后的写法
  5. use_backend backend-foo if { hdr_dom(host) -i foo.com }

后端地址也可以是域名和端口:

  1. # 转发到后端的依然是前端的 host,即 foo.com
  2. server server1 internal.foo.com:80

与 Nginx 的区别
跟 Nginx 不一样的是,HAProxy 在转发时会将来源的 host 一同转发,即当请求 foo.com 时,后端服务器的 host 也是 foo.com,而 Nginx 不会转发 host ,比如,下面是 Nginx 的配置

  1. # 此处需要自行设置 host,才能将前端的 host 转发到后端
  2. proxy_set_header Host foo.com;
  3. proxy_pass http://192.168.0.2:80;

Nginx 使用域名进行转发,效果就跟 HAProxy 一样,会将 host 带到后端。

  1. # 转发到后端的 host 是 foo.com
  2. proxy_pass http://foo.com:80;

HTTPS 代理

HAProxy 默认支持代理 HTTPS 浏览器,实际上它通过 TCP 四层直接实现 TLS 加密内容的转发,它并不需要知道请求的内容。HAProxy 通过读取 TLS 报文中的 SIN 信息来获取所访问域名 host,这样就可以实现代理多站点。

  1. listen https-server
  2. bind :443
  3. mode tcp
  4. option tcplog
  5. tcp-request inspect-delay 5s
  6. tcp-request content accept if { req.ssl_hello_type 1 }
  7. tcp-request content reject if WAIT_END
  8. acl is-foo req.ssl_sni -i foo.com
  9. acl is-foo req.ssl_sni -i www.foo.com
  10. acl is-bar req.ssl_sni -i bar.com
  11. acl is-bar req.ssl_sni -i www.bar.com
  12. use_backend backend-foo if is-foo
  13. use_backend backend-bar if is-bar
  14. backend backend-foo
  15. mode tcp
  16. server server1 192.168.0.10:443
  17. backend backend-bar
  18. mode tcp
  19. server server1 192.168.0.20:443

如果请求没有匹配到任何一个路由时,服务器将会直接断开 TCP 链接。
用户修改 /etc/hosts 即可使用代理,假设 HAProxy 代理服务器的 IP 是 192.168.0.2,则修改如下:

  1. 192.168.0.2 foo.com
  2. 192.168.0.2 www.foo.com
  3. 192.168.0.2 bar.com
  4. 192.168.0.2 www.bar.com