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
第一次接触 HAProxy 与 Stunnel 时的参考资料: http://www.cnblogs.com/wsky/archive/2011/04/06/2007095.html
生成自签名 SSL 证书: https://github.com/chenzhiwei/linux/tree/master/ssl-cert