Haproxy 基础


原文链接: Haproxy 基础

HAProxy 是什么

HAProxy(High Available Proxy) 是基于四层和七层的高可用负载均衡代理服务器,配置简单、支持多达上万条并发请求。HAProxy 的运行模型使得它集成到现在的架构上非常容易和无风险,并且它还免去了将 web 服务器公开到网络上的风险,很多 web 站点都用 HAProxy 来作为七层负载均衡解决方案。

HAProxy 工作原理

HAProxy 由前端(frontend)和后端(backend),前端和后端都可以有多个。也可以只有一个 listen 块来同时实现前端和后端。这里主要讲一下 frontend 和 backend 工作模式。

前端(frontend)区域可以根据 HTTP 请求的 header 信息来定义一些规则,然后将符合某规则的请求转发到相应后端(backend)进行处理。

HAProxy 不能绑定端口

通常是因为 SELinux 打开导致了,运行以下命令即可:setsebool -P haproxy_connect_any=1

还有个原因是要绑定的 IP 地址不在本机,可以在 sysctl.conf 里添加如下内容解决:net.ipv4.ip_nonlocal_bind=1

HAProxy 配置文件

配置段大概配置内容:

  • global :全局配置段,看下内容是什么就知道它是配置什么了
  • defaults :默认配置段,一般配置默认配置。如果下面2段有且和这个不同,则以下面的为准
  • frontend :相当于虚拟主机
  • backend :定义一组一组的后端server
  • listen :既有forntend,又有backend

包含前端和后端的配置文件示例:

global
    daemon
    maxconn 500
    ulimit-n 8000
    user daemon
    group deamon
    chroot /var/empty
    pidfile /var/run/haproxy.pid
    log localhost local0 notice

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend http-front
    bind *:80
    option httpclose
    maxconn 100

    reqirep ^Host:\\ www.abc.com Host:\\ abc.com

    acl host_abc_com hdr(host)      -i abc.com
    acl host_cn      hdr_end(host)  -i .cn
    acl host_xyz     hdr_beg(host)  -i xzy.
    acl url_xxx      url_reg        -i ^/xxx

    use_backend host-abc-com if host_abc_com
    use_backend host-cn      if host_cn
    use_backend host-xyz-url-xxx if host_xyz url_xxx
    default_backend default-servers

backend default-servers
    server default-servers1 127.0.0.1:8000 maxconn 32

backend host-abc-com
    balance roundrobin
    option httpcheck
    option forwardfor
    option httpclose
    option redispatch
    retries 3
    server abc-com1 192.168.1.100:80 check inter 2000 rise 2 fall 3 maxconn 32
    server abc-com2 192.168.1.101:80 check inter 2000 rise 2 fall 3 maxconn 32

backend host-cn
    balance roundrobin
    option httpcheck
    option forwardfor
    option httpclose
    option redispatch
    retries 3
    server abc-com1 192.168.1.100:80 check inter 2000 rise 2 fall 3 maxconn 32
    server abc-com2 192.168.1.101:80 check inter 2000 rise 2 fall 3 maxconn 32
    server abc-com3 192.168.1.102:80 check inter 2000 rise 2 fall 3 maxconn 32 backup

backend host-xyz-url-xxx
    balance roundrobin
    option httpcheck
    option forwardfor
    option httpclose
    option redispatch
    retries 3
    server abc-com1 192.168.1.100:80 check inter 2000 rise 2 fall 3 maxconn 32
    server abc-com2 192.168.1.101:80 check inter 2000 rise 2 fall 3 maxconn 32

包含 listen 区域的配置文件示例:

global
    daemon
    maxconn 256

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

listen http-in
    bind *:80
    server server1 127.0.0.1:8000 maxconn 32

本来想仔细讲解一下配置文件,但是发现 HAProxy 的配置太简单了,文档里写的非常清楚,我如果再详细说一遍的话就等于把 HAProxy 的文档翻译一遍,因此就不多说了。

工作的这一年多时间里,我感觉 HAProxy 是一个既简单又强大的代理,搭建起来非常容易,并且支持对 HTTP 协议头(请求头和响应头)的各种查询、替换和删除。前端时间同事给提了个需求,让 HAProxy 同时更改 HTTP 请求的 Host 和 URI,需要将 Host 中的一个字段放在 URI 的最前面,由于 HAProxy 不支持变量的设定,因此无法完成这个需求(nginx 支持 set 一个变量可以完成这个需求)。

如果你熟悉 syslog(syslog-ng) 的话,那么 HAProxy 日志的配置也很简单,这里不多说,请学习一下 syslog 相关知识,然后再来配置。

HAProxy 做七层代理的话,一般需要和 stunnel 结合起来使用,stunnel 把接收的 HTTPS 请求转发到 HAProxy,然后再由 HAProxy 转发到后端服务器。

stunnel 相关配置介绍

stunnel 配置比较简单,只有一个 stunnel.conf 配置文件,内容如下:

sslVersion=all
fips=no
cert=/etc/stunnel/abc.com.pem
CAfile=/etc/stunnel/abc.com.key
pid=/var/run/stunnel.pid
setuid=root
setgid=root
socket=l:TCP_NODELAY=1
socket=r:TCP_NODELAY=1
output=/var/log/stunnel.log

[https]
accept=443
connect=*:80
TIMEOUTclose=0
xforwardedfor=yes

就这样配置,stunnel 就可以代理 https 请求的 abc.com 了。在 stunnel4.44 版本之前与 HAProxy 结合使用时都需要打一个 HAProxy 提供的 补丁,但之后的版本就不需要打 HAProxy 的补丁了。

haproxy 使用

# haproxy -c -f /etc/haproxy/haproxy.cfg
# haproxy -D -f /etc/haporxy/haproxy.cfg
# haproxy -D -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)

注:很变态的是这些参数的位置不能随意更改。

Haproxy 1.5

从 1.5 版开始,haproxy 支持原生的配置 ssl 证书了,不需要再和 stunnel 配合使用了。并且 TCP 还支持 sni,做代理翻墙很方便。

listen google-services
    bind *:443
    mode tcp
    option  tcplog
    use-server www.google.com if { req_ssl_sni -i www.google.com }
    use-server mail.google.com if { req_ssl_sni -i mail.google.com }
    server www.google.com www.google.com:443
    server mail.google.com mail.google.com:443

Haproxy enable SSL

frontend https
    bind :443 ssl crt /etc/haproxy/server.pem
    default_backend mybackend

backend mybackend
    server s1 127.0.0.1:80

OR

server s2 jizhihuwai.com:443 crt /etc/haproxy/server.pem

server.pem 是用 cat server.crt server.key > /etc/haproxy/server.pem 生成的。

server.crt 一般是 CA 机构给颁发的,而 server.key 是你自己生成的 private key。

相关资料

1.HAProxy 文档(英文,1.4 版): http://haproxy.1wt.eu/download/1.4/doc/configuration.txt

  1. 第一次接触 HAProxy 与 Stunnel 时的参考资料: http://www.cnblogs.com/wsky/archive/2011/04/06/2007095.html

  2. 生成自签名 SSL 证书: https://github.com/chenzhiwei/linux/tree/master/ssl-cert

`