编译安装
源码包下载
[root@localhost ~]# cd /usr/local/src/
[root@localhost ~]# wget http://www.haproxy.org/download/2.4/src/haproxy-2.4.9.tar.gz
# 解压
[root@localhost src]# tar xf haproxy-2.4.9.tar.gz
安装编译的基础环境
yum install gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel net-tools vim iotop zip unzip zlib-devel lrzsz tree screen lsof tcpdump
# lua环境源码下载
wget http://www.lua.org/ftp/lua-5.4.3.tar.gz
tar xf lua-5.4.3.tar.gz
cd lua-5.4.3
make all test
# 验证
[root@localhost lua-5.4.3]# lua -v
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
[root@localhost lua-5.4.3]# ./src/lua -v
Lua 5.4.3 Copyright (C) 1994-2021 Lua.org, PUC-Rio
编译安装haproxy
make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_CPU_AFFINITY=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.4.3/src/ LUA_LIB=/usr/local/src/lua-5.4.3/src/ PREFIX=/apps/haproxy
make install PREFIX=/apps/haproxy
验证HAProxy版本
[root@localhost haproxy-2.4.9]# /apps/haproxy/sbin/haproxy -v
HAProxy version 2.4.9-f8dcd9f 2021/11/24 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.9.html
Running on: Linux 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64
准备启动脚本
cat >> /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
[Install]
WantedBy=multi-user.target
EOF
配置文件
cat /etc/haproxy/haproxy.cfg
global # 全局配置
maxconn 100000 # 每个haproxy进程最大的并发连接数
chroot /apps/haproxy # 锁定运行目录
# stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin # socket文件
stats socket /var/lib/haproxy/haproxy1.sock mode 600 level admin process 1 # 多进程模式下,需要每个进程定义一个socket文件
stats socket /var/lib/haproxy/haproxy2.sock mode 600 level admin process 2
stats socket /var/lib/haproxy/haproxy3.sock mode 600 level admin process 3
stats socket /var/lib/haproxy/haproxy4.sock mode 600 level admin process 4
uid 99 # 运行haproxy的用户uid
gid 99 # 运行haproxy的组id
daemon # 以守护进程运行
nbproc 4 # 开启haproxy的进程个数,一般于cpu保持一直
cpu-map 1 0 # 第一个进程绑定到cpu0上
cpu-map 2 1
cpu-map 3 2
cpu-map 4 3
pidfile /var/lib/haproxy/haproxy.pid # haproxy的pid文件路径,这个路径需要手动创建
log 127.0.0.1 local3 info # 定义syslog服务器
defaults # 默认配置项,针对以下的frontend、backend和lsiten⽣效
option http-keep-alive # 开启与客户端的会话保持
option forwardfor # 透传客户端真实IP至后端web服务器
maxconn 100000
mode http #设置默认工作类型
timeout connect 300000ms # 客户端请求从haproxy到后端server的最长连接等待时间(TCP之前)
timeout client 300000ms # 设置haproxy与客户端的最长非活动时间
timeout server 300000ms # 客户端请求从haproxy到后端服务端的请求处理超时时长(TCP之后),这个时间设置要稍微长一点
frontend+backend配置示例:
frontend WEB_PORT_80
bind 192.168.119.248:80 # 监听的地址和端口
mode http # 工作类型
use_backend web_prot_http_nodes # 指定backend的名字
backend web_prot_http_nodes
mode http # 工作类型
option forwardfor # 这里如果不定义,会使用defaults配置段的配置
server 192.168.119.101 192.168.119.101:8080 check inter 3000 fall 3 rise 5
# check inter 3000 fall 2 rise 5
# check 对指定real进行健康状态检查
# inter 健康状态检查间隔时间,默认2000 ms
# fall 后端服务器失效检查次数,默认为3
# rise 后端服务器从下线恢复检查次数,默认为2
server 192.168.119.102 192.168.119.102:8080 check inter 3000 fall 3 rise 5
listen替代frontend+backend
listen web_port
bind 192.168.119.101:80 # 监听的地址和端口
mode http # 工作类型
log global
server web1 192.168.119.103:80 check inter 3000 fall 2 rise 5
server web2 192.168.119.104:80 check inter 3000 fall 2 rise 5
准备两台nginx提供web服务
yum install nginx -y
web1
echo web1 > /usr/share/nginx/html/index.html
web2
echo web2 > /usr/share/nginx/html/index.html
测试:
[root@localhost nginx]# while true;do curl http://192.168.119.101;sleep 0.5 ;done
web1
web2
web1
web2
web1
web2
调度算法
静态算法
静态算法:按照事先定义好的规则轮询公平调度,不关⼼后端服务器的当前负载、链接数和响应速度等,且⽆法实时修改权重,只能靠重启HAProxy⽣效。
static-rr:基于权重的轮询调度,不支持权重的运行时调整及后端服务器慢启动,其后端主机数量没有限制
first:根据服务器在列表中的位置,自上⽽下进行调度,但是其只会当第⼀台服务器的连接数达到上限,新请求才会分配给下⼀台服务,因此会忽略服务器的权重设置。
动态算法
roundrobin:基于权重的轮询动态调度算法,支持权重的运行时调整,不完全等于lvs中的rr轮训模式,HAProxy中的roundrobin⽀持慢启动(新加的服务器会逐渐增加转发数),其每个后端backend中最多支持4095个real server,roundrobin为默认调度算法,且支持对real server权重动态调整。
leastconn加权的最少连接的动态,支持权重的运行时调整和慢启动,即当前后端服务器连接最少的优先调度(新客户端连接),⽐较适合长连接的场景使用,⽐如MySQL等场景。
其他算法
其他部分算法即可作为静态算法,⼜可以通过选项成为动态算法(hash-type consistent)
source:源地址hash,基于用户源地址hash并将请求转发到后端服务器,默认为静态即取模⽅式,但是可以通过hash-type⽀持的选项更改,后续同⼀个源地址请求将被转发至同⼀个后端web服务器,⽐较适用于session保持/缓存业务等场景。
uri:基于对用户请求的uri做hash并将请求转发到后端指定服务器,也可以通过map-based和consistent定义使用取模法还是⼀致性hash。
url_param:url_param对用户请求的url中的 params 部分中的参数name作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同⼀个用户的请求始终发往同⼀个real server
hdr:针对用户每个http头部(header)请求中的指定信息做hash,此处由 name指定的http⾸部将会被取出并做hash计算,然后由服务器总权重相除以后派发至某挑出的服务器,假如⽆有效的值,则会使用默认的轮询调度。
rdp-cookie:rdp-cookie可以实现对windows远程桌⾯的负载,如果有多个后端windows Server服务器,rdp-cookie可以实现同⼀个window server的请求始终被转发给同⼀个后端服务器,如果之前从未访问过,那么第⼀次使用连接roundrobin算法计算出⼀个后端服务器并进行转发。
random:在1.9版本开始增加⼀个叫做random的负载平衡算法,其基于⼀个随机数作为⼀致性hash的key,随机负载平衡对于⼤型服务器场或经常添加或删除服务器非常有用。
static-rr--------->tcp/http 静态
first------------->tcp/http 静态
roundrobin-------->tcp/http 动态
leastconn--------->tcp/http 动态
random------------>tcp/http 动态
source------------>tcp/http
Uri--------------->http
url_param--------->http 取决于hash_type是否consistent
hdr--------------->http
rdp-cookie-------->tcp
# 如果mode是tcp,算法用的是只能用http的算法,例如url_param,会自动把算法改为roundrobin
配置监控页面:
listen stats
mode http
bind 0.0.0.0:9999 # 监听的IP和端口
stats enable
log global
stats uri /haproxy-status # http://<IP>:9999/haproxy-status
stats auth haadmin:q1w2e3r4ys # 配置登录的用户名和密码,如果不加此项,打开页面不需要认证
# stats admin if TRUE # 启用状态页的管理功能,一般不开启
状态页说明
pid = 3698 (process #2, nbproc = 2, nbthread = 1) #pid为当前pid号,process为当前进程号,nbproc和nbthread为⼀共多少进程和每个进程多少个线程
uptime = 0d 0h00m08s #启动了多长时间
system limits: memmax = unlimited; ulimit-n = 131124 #系统资源限制:内存/最⼤打开文件数/
maxsock = 131124; maxconn = 65536; maxpipes = 0 #最⼤socket连接数/单进程最⼤连接数/最⼤管道数maxpipes
current conns = 1; current pipes = 0/0; conn rate = 1/sec #当前连接数/当前管道数/当前连接速率
Running tasks: 1/9; idle = 100 % #运行的任务/当前空闲率
active UP:#在线服务器
backup UP:#标记为backup的服务器
active UP, going down:#监测未通过正在进⼊down过程
backup UP, going down:#备份服务器正在进⼊down过程
active DOWN, going up:#down的服务器正在进⼊up过程
backup DOWN, going up:#备份服务器正在进⼊up过程
active or backup DOWN:#在线的服务器或者是backup的服务器已经转换成了down状态
not checked:#标记为不监测的服务器
active or backup DOWN for maintenance (MAINT) #active或者backup服务器⼈为下线的
active or backup SOFT STOPPED for maintenance #active或者backup被⼈为软下线(⼈为将weight改成0)
基于haproxy,实现网页动静分离
访问控制列表(ACL,Access Control Lists)是⼀种基于包过滤的访问控制技术,它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配),即对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求⽅法、URL、文件后缀等信息内容进行匹配并执行进⼀步操作,⽐如允许其通过或丢弃。
acl <aclname> <criterion> [flags] [operator] [<value>]
acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
匹配规范
hdr([<name> [,<occ>]]):完全匹配字符串,header的指定信息
hdr_beg([<name> [,<occ>]]):前缀匹配,header中指定匹配内容的begin
hdr_end([<name> [,<occ>]]):后缀匹配,header中指定匹配内容end
hdr_dom([<name> [,<occ>]]):域匹配,header中的domain name
hdr_dir([<name> [,<occ>]]):路径匹配,header的uri路径
hdr_len([<name> [,<occ>]]):长度匹配,header的长度匹配
hdr_reg([<name> [,<occ>]]):正则表达式匹配,自定义表达式(regex)模糊匹配
hdr_sub([<name> [,<occ>]]):⼦串匹配,header中的uri模糊匹配
dst 目标IP
dst_port 目标PORT
src 源IP
src_port 源PORT
⽰例:
hdr(<string>) 用于测试请求头部首部指定内容
hdr_dom(host) 请求的host名称,如 www.12345.com
hdr_beg(host) 请求的host开头,如 www. img. video. download. ftp.
hdr_end(host) 请求的host结尾,如 .com .net .cn
path_beg 请求的URL开头,如/static、/images、/img、/css
path_end 请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg
有些功能是类似的,⽐如以下⼏个都是匹配用户请求报文中host的开头是不是www:
acl short_form hdr_beg(host) www.
acl alternate1 hdr_beg(host) -m beg www.
acl alternate2 hdr_dom(host) -m beg www.
acl alternate3 hdr(host) -m beg www.
匹配模式
-i 不区分⼤⼩写
-m 使用指定的pattern匹配⽅法
-n 不做DNS解析
-u 禁⽌acl重名,否则多个同名ACL匹配或关系
global
maxconn 100000
chroot /apps/haproxy
stats socket /var/lib/haproxy/haproxy1.sock mode 600 level admin process 1 # 多进程模式下,需要每个进程定义一个socket文件
stats socket /var/lib/haproxy/haproxy2.sock mode 600 level admin process 2
stats socket /var/lib/haproxy/haproxy3.sock mode 600 level admin process 3
stats socket /var/lib/haproxy/haproxy4.sock mode 600 level admin process 4
uid 99
gid 99
daemon
nbproc 4
cpu-map 1 0
cpu-map 2 1
cpu-map 3 2
cpu-map 4 3
pidfile /var/lib/haproxy/haproxy.pid
log 127.0.0.1 local3 info
defaults
option http-keep-alive
option forwardfor
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
listen web_port
bind 192.168.119.101:80
mode http
log global
####################################
acl php_server path_end -i .php
# php_server ACL的名称
# path_end 请求的URL中资源的结尾
# -i 不区分大小写
use_backend php_server_host if php_server
# 如果匹配上名称为php_server的acl,就转发到php_server_host后端主机组
####################################
acl image_server path_end -i .jpg .png .jpeg .gif
use_backend image_server_host if image_server
####################################
backend php_server_host
mode http
server web1 192.168.119.103 check inter 3000 fall 2 rise 5
backend backend image_server_host
mode http
server web2 192.168.119.104 check inter 3000 fall 2 rise 5
使用haproxy,实现https
证书制作
# mkdir /apps/haproxy/certs
# cd /apps/haproxy/certs
# openssl genrsa -out haproxy.key 2048
# openssl req -new -x509 -key haproxy.key -out haproxy.crt -subj "/CN=www.12345.net"
# cat haproxy.key haproxy.crt > haproxy.pem
# openssl x509 -in haproxy.pem -noout -text #查看证书
配置:
#web server http
frontend web_server-http
bind 192.168.119.101:80
redirect scheme https if !{ ssl_fc } # 全站https主要选项
mode http
use_backend web_host
# web server https
frontend web_server-https
bind 192.168.119.101:443 ssl crt /apps/haproxy/certs/haproxy.pem
mode http
use_backend web_host
backend web_host
mode http
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server web1 192.168.119.103:80 check inter 2000 fall 3 rise 5
server web2 192.168.119.104:80 check inter 2000 fall 3 rise 5