1.安装haproxy
wget https://www.haproxy.org/download/2.4/src/haproxy-2.4.3.tar.gz
tar -zxvf haproxy-2.4.3.tar.gz
cd haproxy-2.4.3
#uname -r查看下内核版本,centos7.x是linux31、centos6.x是linux26,如果不行还可以试试(linux2628、linux-glibc)
make TARGET=linux31 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1
make install PREFIX=/usr/local/haproxy
2.Linux内核优化
为了让系统能够支持更大的并发,我们可以优化一下linux内核
打开/etc/sysctl.conf这个文件
在里面增加以下配置,然后保存
net.core.somaxconn = 65535
运行下面这行命令使配置生效
打开/etc/security/limits.conf这个文件
在这个文件中加入下面这行配置
重启一下服务器,服务器重启后该配置才会生效
3.haproxy配置
进入haproxy安装目录
在haproxy安装目录下创建一个etc目录
切换到etc目录下
在etc目录下,创建一个haproxy.cfg文件
haproxy.cfg内容如下
daemon
log 127.0.0.1 local6
maxconn 65535
chroot /usr/local/haproxy
pidfile /var/run/haproxy.pid
defaults
mode http
option httplog
option forwardfor
log global
option http-server-close
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 65535
frontend web_in
bind *:80
acl is_web hdr_beg(host) -i www.zhiboblog.com
use_backend web_servers if is_web
backend web_servers
balance roundrobin
#balance source
server server1 45.32.75.138:80 check inter 2000 rise 2 fall 3
server server2 149.28.91.22:80 check inter 2000 rise 2 fall 3
4.启动haproxy
启动haproxy的方法(这种方法启动后,想要关闭,只能杀掉进程,比较麻烦)
为了让启动更方便,我们可以用systemctl来管理,systemctl可以很方便的实现haproxy启动、重启、关闭
在/usr/lib/systemd/system/目录下创建一个haproxy.service
haproxy.service内容如下:
Description=haproxy
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/etc/haproxy.cfg
[Install]
WantedBy=multi-user.target
这样我们就可以用systemctl来启动haproxy了
systemctl start haproxy
//重启
systemctl restart haproxy
//关闭
systemctl stop haproxy
设置haproxy开机自启动
关掉服务器防火墙
systemctl stop firewalld
//禁止防火墙开机启动
systemctl disable firewalld
然后现在访问你的域名,就会进行负载均衡,轮询分配到配置中设置的那两台真实服务器上
5.haproxy的八种负载均衡算法
2.balance source #将用户来源IP经过hash计算后,指定到固定的真实服务器上(生产环境下推荐这种方式)
3.balance static-rr # 根据权重
4.balance leastconn # 最少连接者先处理
5.balance uri # 根据请求的URI
6.balance url_param,# 根据请求的URl参数
7.balance hdr(name) # 根据HTTP请求头来锁定每一次HTTP请求
8.balance rdp-cookie(name) # 根据据cookie(name)来锁定并哈希每一次TCP请求
我这里为了测试,用的是balance roundrobin这种算法,实际生产环境中推荐采用balance source这种算法。
6.haproxy配置ssl证书
配置ssl证书,需要在haproxy.cfg配置文件中增加几行配置
首先在global中添加下面这行
然后在frontend中增加下面这行,这里的ssl.pem是由crt和key两个文件拼接在一起的,拼接好后将ssl证书放到usr/local/haproxy/etc/目录下
如果想实现http自动跳转到https,可以在frontend中再增加下面这行
redirect scheme https if !{ ssl_fc }
//只针对www.zhiboblog.com进行跳转
redirect scheme https if { hdr_beg(host) -i www.zhiboblog.com } !{ ssl_fc }
//只针对zhiboblog.com所有子域名跳转
redirect scheme https if { hdr_reg(host) -i ^[a-zA-Z0-9_]+.zhiboblog.com } !{ ssl_fc }
//只针对zhiboblog.com主域名及其所有子域名跳转
redirect scheme https if { hdr_end(host) -i zhiboblog.com } !{ ssl_fc }
只需要这三行配置,就可以实现https访问负载均衡了。
完整配置如下:
daemon
log 127.0.0.1 local6
maxconn 65535
chroot /usr/local/haproxy
pidfile /var/run/haproxy.pid
tune.ssl.default-dh-param 2048
defaults
mode http
option httplog
option forwardfor
log global
option http-server-close
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 65535
frontend web_in
bind *:80
bind *:443 ssl crt /usr/local/haproxy/etc/ssl.pem
redirect scheme https if !{ ssl_fc }
acl is_web hdr_beg(host) -i www.zhiboblog.com
use_backend web_servers if is_web
backend web_servers
balance roundrobin
#balance source
server server1 45.32.75.138:80 check inter 2000 rise 2 fall 3
server server2 149.28.91.22:80 check inter 2000 rise 2 fall 3
7.haproxy配置多站点ssl
下面我配置了三个站点:www.a.com、www.b.com、www.c.com
www.a.com和www.b.com是配置了ssl证书的,www.c.com是没有配置ssl证书的。
我们既可以用配置了ssl的站点,也可以用不带ssl的站点,这样很灵活,配置起来也很方便。
daemon
log 127.0.0.1 local6
maxconn 65535
chroot /usr/local/haproxy
pidfile /var/run/haproxy.pid
tune.ssl.default-dh-param 2048
defaults
mode http
option httplog
option forwardfor
log global
option http-server-close
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 65535
frontend web_in
bind *:80
#配置多个站点ssl,只需要在下面这行后面加"crt 证书路径",有几个加几个
bind *:443 ssl crt /usr/local/haproxy/etc/www.a.com.pem crt /usr/local/haproxy/etc/www.b.com.pem
#需要强制跳转https的域名,如果不需要强制跳转可以注释掉下面这两行
acl ssl hdr_reg(host) -i ^(www.a.com|www.b.com)$
redirect scheme https code 301 if !{ ssl_fc } ssl
acl is_sitea hdr_beg(host) -i www.a.com
use_backend sitea_servers if is_sitea
acl is_siteb hdr_beg(host) -i www.b.com
use_backend siteb_servers if is_siteb
acl is_sitec hdr_beg(host) -i www.c.com
use_backend sitec_servers if is_sitec
#在没有匹配到的情况下,默认转发到default_servers这个后端服务池
default_backend default_servers
backend default_servers
balance roundrobin
#balance source
server server1 192.168.245.1:80 check inter 2000 rise 2 fall 3
server server2 192.168.245.2:80 check inter 2000 rise 2 fall 3
backend sitea_servers
balance roundrobin
#balance source
server server1 192.168.245.1:80 check inter 2000 rise 2 fall 3
server server2 192.168.245.2:80 check inter 2000 rise 2 fall 3
backend siteb_servers
balance roundrobin
#balance source
server server3 192.168.245.3:80 check inter 2000 rise 2 fall 3
server server4 192.168.245.4:80 check inter 2000 rise 2 fall 3
backend sitec_servers
balance roundrobin
#balance source
server server5 192.168.245.5:80 check inter 2000 rise 2 fall 3
server server6 192.168.245.6:80 check inter 2000 rise 2 fall 3
如果要匹配泛域名,如:*.zhiboblog.com,该怎么匹配呢?
可以用hdr_end(host) -i zhiboblog.com来匹配,之前我们匹配域名都是用的hdr_beg,hdr_beg是从域名开头开始匹配,hdr_end是从域名结尾开始匹配。
8.haproxy负载均衡websocket
haproxy不仅能负载均衡普通的http请求,也可以负载均衡websocket请求。
frontend ws_in
bind *:2348
acl hdr_connection_upgrade hdr(Connection) -i upgrade
acl hdr_upgrade_websocket hdr(Upgrade) -i websocket
use_backend websockets if hdr_connection_upgrade hdr_upgrade_websocket
backend websockets
balance source
server web1 192.168.1.13:2348 check inter 2000 rise 3 fall 3 weight 1
9.haproxy新版本与老版本的差别
haproxy2.0版本之前,安装的时候TARGET是linux2628
haproxy2.0版本之后,安装的时候TARGET是linux-glibc
老版本中,global中有一个nbproc参数,是指定进程数的,在新版本中nbproc被废弃了,如果用的是新版本,可以把nbproc这一行注释掉。