一、 HAProxy介绍
HAProxy是法国开发者威利塔罗(Willy Tarreau)在2000年使用C语言开发的一个开源软件,是一款具备高并发(一万以上)、高性能的TCP和HTTP负载均衡器,支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计,目前最新TLS版本为2.2。
HAProxy是可提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,是免费、快速并且可靠的一种解决方案。HProxy非常适用于并发大(并发达1w以上) web站点,这些站点通常又需要会话保持或七层处理。HAProxy的运行模式使得它可以很简单安全的整合至当前的架构中,同时可以保护web服务器不被暴露到网络上。
支持功能:
- TCP 和 HTTP反向代理
- SSL/TSL服务器
- 可以针对HTTP请求添加cookie,进行路由后端服务器
- 可平衡负载至后端服务器,并支持持久连接
- 支持所有主服务器故障切换至备用服务器 keepalive
- 支持专用端口实现监控服务
- 支持停止接受新连接请求,而不影响现有连接
- 可以在双向添加,修改或删除HTTP报文首部字段
- 响应报文压缩
- 支持基于pattern实现连接请求的访问控制
- 通过特定的URI(url)为授权用户提供详细的状态信息
二、 安装Haproxy
1. yum安装
CentOS 7 的默认的base仓库中包含haproxy的安装包文件,但是版本比较旧,是1.5.18的版本,距离当前版本已经有较长时间没有更新,由于版本比较旧所以有很多功能不支持,如果对功能和性能没有要求可以使用此版本,否则推荐使用新版本。
yum install haproxy -y
2. rpm包安装
官方没有提供rpm相关的包,可以从第三方网站下载rpm包
点击查看代码
[root@node1 ~]# cd /data
[root@node1 data]# rz //上传安装包
[root@node1 data]# yum install -y rh-haproxy18-haproxy-1.8.24-3.el7.x86_64.rpm //安装依赖关系
[root@node1 data]# yum install -y rh-haproxy18-runtime-3.1-2.el7.x86_64.rpm
[root@node1 data]# systemctl start rh-haproxy18-haproxy.service //开启服务
3. 编译安装
由于CentOS7 之前版本自带的lua版本比较低并不符合HAProxy要求的lua最低版本(5.3)的要求,因此需要编译安装较新版本的lua环境,然后才能编译安装HAProxy。
- 安装lua
点击查看代码
[root@node1 ~]# cd /data
[root@node1 data]# ls
haproxy-2.4.25.tar.gz lua-5.4.4.tar.gz
[root@node1 data]# tar xf lua-5.4.4.tar.gz
[root@node1 data]# ls
haproxy-2.4.25.tar.gz lua-5.4.4 lua-5.4.4.tar.gz
[root@node1 data]# cd lua-5.4.4/
[root@node1 lua-5.4.4]# ls
doc Makefile README src
[root@node1 lua-5.4.4]# make all test
[root@node1 lua-5.4.4]# cd src/
[root@node1 src]# ./lua -v //查看版本
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
[root@node1 lua-5.4.4]# cd /data
[root@node1 data]# ln -s lua-5.4.4 lua //创建软链接
- 编译安装haproxy
点击查看代码
[root@node1 data]# yum install -y gcc openssl-devel pcre-devel systemd-devel //安装依赖环境
[root@node1 data]# tar xf haproxy-2.4.25.tar.gz
[root@node1 data]# cd haproxy-2.4.25/
[root@node1 haproxy-2.4.25]# make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/data/lua/src/ LUA_LIB=/data/lua/src/
[root@node1 haproxy-2.4.25]# make install PREFIX=/apps/haproxy
[root@node1 haproxy-2.4.25]# ln -s /apps/haproxy/sbin/haproxy /usr/sbin/ //软链接
[root@node1 haproxy-2.4.25]# haproxy -v //查看版本信息
[root@node1 haproxy-2.4.25]# tee /usr/lib/systemd/system/haproxy.service <<eof
>
> [Unit]
> Description=HAProxy Load Balancer
> After=syslog.target network.target
>
> [Service]
> ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
> ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid
> ExecReload=/bin/kill -USR2 $MAINPID
> LimitNOFILE=100000
>
> [Install]
> WantedBy=multi-user.target
>
>
> eof
[root@node1 haproxy-2.4.25]# mkdir /etc/haproxy
[root@node1 haproxy-2.4.25]# cd /etc/haproxy
[root@node1 haproxy]# vim haproxy.cfg
[root@node1 haproxy]# mkdir /var/lib/haproxy //pid文件路径
[root@node1 haproxy]# useradd -r -s /sbin/nologin haproxy //创建用户
[root@node1 haproxy]# systemctl start haproxy.service //开启服务
三、配置文件详解
配置文件官方帮助文档:docs.haproxy.org/2.4/configu…
HAProxy 的配置文件haproxy.cfg由两大部分组成,分别是global和proxies部分
-
global:全局配置段
- 进程及安全配置相关的参数
- 性能调整相关参数
- Debug参数
-
proxies:代理配置段
- defaults:为frontend,backend,listen提供默认配置
- frontend:前端,相当于nginx中的server {} 模块。 定义虚拟机、监听、分配请求
- backend:后端,相当于nginx中的upstream {} 模块。 真实服务器
- listen:同时拥有前端和后端配置,配置简单,生产环境中推荐使用
1.global配置
点击查看代码
global
maxconn 100000 //最大连接数
chroot /apps/haproxy //禁锢haproxy进程只可以访问 /apps/haproxy 文件夹
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin //指明socket文件位置
uid 99 //uid为99
gid 99 //gid为99
daemon //后台方式 守护进程
#nbproc 4 //开启的进程数
#cpu-map 1 0 //进程绑定cpu
#cpu-map 2 1
#cpu-map 3 2
#cpu-map 4 3
pidfile /var/lib/haproxy/haproxy.pid //指定pid文件路径
log 127.0.0.1 local3 info //定义全局的syslog服务器
状态页
点击查看代码
//特殊配置 状态页
listen stats
mode http //代理类型 7层http 4层tcp
bind 0.0.0.0:9999 //监听地址+端口
stats enable //启用统计功能
log global //日志 使用全局配置
stats uri /haproxy-status //url为 /haproxy-status
stats auth haadmin:123456 //用户名、密码
指定进程线程个数
点击查看代码
nbproc 4 //开启的haproxy work 进程数,默认进程数是一个
#nbthread 1 //指定每个haproxy进程开启的线程数,默认为每个进程一个线程。和多进程 nbproc配置互斥(版本有关,CentOS8的haproxy1.8无此问题)
cpu亲缘性
点击查看代码
cpu-map 1 0 //绑定haproxy worker 进程至指定CPU,将第1个work进程绑定至0号CPU
cpu-map 2 1 //绑定haproxy worker 进程至指定CPU,将第2个work进程绑定至1号CPU
多线程和多进程
点击查看代码
nbproc 2
stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1
stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2
日志
HAproxy本身不记录客户端的访问日志。此外为减少服务器负载,一般生产中HAProxy不记录日志,也可以配置HAProxy利用rsyslog服务记录日志到指定日志文件服务器中。
点击查看代码
vim /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
local3.* /var/log/haproxy.log
Proxies配置
listen简化配置
使用listen替换frontend和backend的配置方式,可以简化设置,通常只用于TCP协议的应用
示例:加入健康性检测check(默认无后端健康性检测)
7-1haproxy服务器:
点击查看代码
[root@node1 ~]# vim /etc/haproxy/haproxy.cfg
listen lkk
bind 192.168.204.10:80
mode http
log global
server web1 192.168.204.20:80 check
server web2 192.168.204.30:80 check
[root@node1 ~]# systemctl restart haproxy.service
[root@node1 ~]# ss -natp | grep 80
LISTEN 0 128 192.168.204.10:80 *:* users:(("haproxy",pid=45766,fd=7))
后端web1服务器:
点击查看代码
[root@node2 ~]# yum install httpd -y
[root@node2 ~]# cd /var/www/html/
[root@node2 html]# echo 7-2 > index.html
[root@node2 html]# systemctl start httpd
后端web2服务器:
点击查看代码
[root@node3 ~]# yum install httpd -y
[root@node3 ~]# cd /var/www/html/
[root@node3 html]# echo 7-2 > index.html
[root@node3 html]# systemctl start httpd
客户端访问:
点击查看代码
[root@localhost ~]# curl 192.168.204.10
7-3
[root@localhost ~]# curl 192.168.204.10
7-2
[root@localhost ~]# curl 192.168.204.10
7-3
[root@localhost ~]# curl 192.168.204.10
7-2
frontend、backend
示例1:前后端分离
点击查看代码
[root@node1 ~]# vim /etc/haproxy/haproxy.cfg
frontend lkk
bind 192.168.204.10:80
use_backend web
backend web
server web1 192.168.204.20:80 check
server web2 192.168.204.30:80 check weight 2
[root@node1 ~]# systemctl restart haproxy.service
后端服务器web1,web2设置同上;
示例2:跳转到baidu
点击查看代码
[root@node1 ~]# vim /etc/haproxy/haproxy.cfg
frontend lkk
bind 192.168.204.10:80
use_backend web
backend web
server web1 192.168.204.20:80 check
server web2 192.168.204.30:80 check redir http://www.baidu.com //如多跳转到web2就访问baidu
[root@node1 ~]# systemctl restart haproxy.service
子配置文件
点击查看代码
[root@node1 ~]# mkdir /etc/haproxy/conf.d/ //创建子配置目录
[root@node1 ~]# sed -n '40,$p' /etc/haproxy/haproxy.cfg
frontend lkk
bind 192.168.204.10:80
use_backend web
backend web
server web1 192.168.204.20:80 check
server web2 192.168.204.30:80 check
[root@node1 ~]# sed -n '40,$p' /etc/haproxy/haproxy.cfg > /etc/haproxy/conf.d/test.cfg
//注意配置文件名要以 cfg 结尾
[root@node1 ~]# vim /etc/haproxy/haproxy.cfg //注释掉原来的40行开始
[root@node1 ~]# vim /usr/lib/systemd/system/haproxy.service //将子配置文件的位置加入进来
[root@node1 ~]# systemctl daemon-reload
[root@node1 ~]# systemctl restart haproxy.service
四、调度算法
HAProxy通过固定参数 balance 指明对后端服务器的调度算法,该参数可以配置在listen或backend选项中。
HAProxy的调度算法分为静态和动态调度算法,但是有些算法可以根据参数在静态和动态算法中相互转换。
- 静态算法
静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。
1.1 socat工具
对服务器动态权重和其它状态可以利用 socat工具进行调整,Socat 是 Linux 下的一个多功能的网络工具,名字来由是Socket CAT,相当于netCAT的增强版。Socat 的主要特点就是在两个数据流之间建立双向通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、Socket文件等。
点击查看代码
`示例:利用工具socat 对服务器动态权重调整`
[root@node1 ~]# yum install socat -y //安装socat工具
//查看soket文件帮助
[root@node1 ~]# echo "help" | socat stdio /var/lib/haproxy/haproxy.sock
//查看服务器的权重 web是后端的名字 web1是真实服务器的名字
[root@node1 ~]# echo "get weight web/web1" | socat stdio /var/lib/haproxy/haproxy.sock
1 (initial 1)
//set修改权重
[root@node1 ~]# echo "set weight web/web1 3" | socat stdio /var/lib/haproxy/haproxy.sock
[root@node1 ~]# echo "get weight web/web1" | stdio /var/lib/haproxy/haproxy.sock
3 (initial 1)
1.2 static-rr
static-rr:基于权重的轮询调度,不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的 wrr。
点击查看代码
balance static-rr
1.3 first
first:根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少不支持用socat进行动态修改权重,可以设置0和1,可以设置权重值但无效。
点击查看代码
balance first
- 动态算法
动态算法:基于后端服务器状态进行调度适当调整,优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启。
2.1 roundrobin (默认算法)
roundrobin:基于权重的轮询动态调度算法,支持权重的运行时调整,不同于lvs中的rr轮训模式,HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),其每个后端backend中最多支持4095个real server,支持对real server权重动态调整,roundrobin为默认调度算法,此算法使用广泛。
js复制代码
点击查看代码
balance roundrobin
2.2 leastconn
leastconn 加权的最少连接的动态,支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接),比较适合长连接的场景使用,比如:MySQL等场景。
点击查看代码
balance leastconn
2.3 random
在1.9版本开始增加 random 的负载平衡算法,其基于随机数作为一致性hash的key,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用,支持weight的动态调整,weight较大的主机有更大概率获取新请求。
点击查看代码
balance random
- 其他算法
其它算法即可作为静态算法,又可以通过选项成为动态算法。
3.1 source
源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web服务器。
此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type选项进行更改这个算法一般是在不插入Cookie的TCP模式下使用,也可给不支持会话cookie的客户提供最好的会话粘性,适用于session会话保持但不支持cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash。
点击查看代码
balance source
hash-type consistent //一致性hash
3.2 uri
基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后,根据最终结果将请求转发到后端指定服务器,适用于后端是缓存服务器场景,默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。
点击查看代码
balance uri
3.3 url_param
url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server,如果无没key,将按roundrobin算法
点击查看代码
balance url_param userid(自定义)
假设:
url = http://www.laowang.com/foo/bar/index.php?key=value
则:
host = "www.laowang.com"
url_param = "key=value"
3.4 hdr
针对用户每个http头部(header)请求中的指定信息做hash,此处由 name 指定的http首部将会被取出并做hash计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
点击查看代码
balance hdr(User-Agent)
#balance hdr(host)