haproxy -c -f /etc/haproxy/conf.d/test.cfg #指定相关目录检查文件
目录
HAProxy 简介
为什么使用负载均衡
负载均衡类型
编译安装 HAProxy
编辑编辑
HAProxy 基于 Docker 部署
HAProxy 基础配置
Global 配置参数说明
HAProxy日志配置
启动本地和远程日志
Proxies 配置
Proxies配置-defaults
Proxies配置-listen 简化配置
Proxies配置-frontend
Proxies配置-backend
使用子配置文件保存配置
HAProxy 调度算法
静态算法
Socat 工具 不用修改文件通过命令就可以做到实现脚本的批量修改
static-rr 算法 基于权重的轮询调度
first 算法 根据服务器在列表中的位置,自上而下进行调度
动态算法
roundrobin 算法
leastconn 算法 前连接最少的后服务器而非权重进行优先调度(新客户端连接)
random 算法 基于随机数作为一致性hash的key,随机负载平衡
其他算法 其它算法即可作为静态算法,又可以通过选项成为动态算法
map-base 取模法
一致性 hash
一致性hash配置示例 \ #默认静态算法基于取模的方法,加上他改为动态算法
uri 算法 对总权重进行取模后,根据最终结果将请求转发到后端指定服务器
url_param 算法 根据uip来做调度的依据
hdr 算法 针对不同的浏览器进行调度
算法总结
HAProxy 高级功能
基于 Cookie 的会话保持
状态页配置项
启用状态页示例
编辑编辑
登录状态页说明
利用状态页实现haproxy服务器的健康性检查
IP透传
四层IP透传 只能通过四层代理访,本机无法访问,不推荐
七层IP透传
报文修改
自定义日志格式
压缩功能
后端服务器健康性监测
基于应用层http协议进行健康性检测
ACL
定义ACL配置选项
ACL-Name
ACL匹配模式
多个ACL的逻辑处理
ACL示例:域名匹配
定义 HAProxy 错误界面
HAProxy Https 实现
HAProxy 简介
负载均衡:Load Balance,简称LB,是一种服务或基于硬件设备等实现的高可用反向代理技术,负载均衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备,从而提高了公司业务的并发处理能力、保证了业务的高可用性、方便了业务后期的水平动态扩展
阿里云SLB介绍 :https://yq.aliyun.com/articles/1803
为什么使用负载均衡
- 增加业务并发访问及处理能力-->解决单服务器瓶颈问题
- 节约公网IP地址-->降低IT支出成本
- 隐藏内部服务器IP-->提高内部服务器安全性
- Web服务器的动态水平扩展-->对用户无感知
- 负载均衡配置简单-->固定格式的配置文件
- 负载均衡功能丰富-->支持四层和七层,支持动态下线主机
- 负载均衡性能较强-->并发数万甚至百万
负载均衡类型
七层:
LVS:Linux Virtual Server
Nginx:1.9版之后
HAProxy:High Availability Proxy
七层:
HAProxy
Nginx
硬件:
F5 https://f5.com/zh
Netscaler https://www.citrix.com.cn/products/citrix-adc/
Array https://www.arraynetworks.com.cn/
深信服 http://www.sangfor.com.cn/
北京灵州 http://www.lingzhou.com.cn/cpzx/llfzjh/
应用场景
四层:Redis、Mysql、RabbitMQ、Memcached等
七层:Nginx、Tomcat、Apache、PHP、图片、动静分离、API等
支持功能:
TCP 和 HTTP反向代理
SSL/TSL服务器
可以针对HTTP请求添加cookie,进行路由后端服务器
可平衡负载至后端服务器,并支持持久连接
支持所有主服务器故障切换至备用服务器
支持专用端口实现监控服务
支持停止接受新连接请求,而不影响现有连接
可以在双向添加,修改或删除HTTP报文首部
响应报文压缩
支持基于pattern实现连接请求的访问控制
通过特定的URI为授权用户提供详细的状态信息
官方之有ububtu的包没有红帽的包
打开链接: https://haproxy.debian.net/ ,选择合适的版本,会自动出现下面安装提示
root@ubuntu200 ~]#apt-get install software-properties-common
[root@ubuntu2004 ~]#add-apt-repository ppa:vbernat/haproxy-2.6
编译安装 HAProxy
解决 lua 环境
HAProxy 支持基于lua实现功能扩展,lua是一种小巧的脚本语言,于1993年由巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组开发,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua 官网:www.lua.org
Lua 应用场景
- 游戏开发
- 独立应用脚本
- Web 应用脚本
- 扩展和数据库插件,如MySQL Proxy
- 安全系统,如入侵检测系统
HAProxy要求的lua最低版本(5.3)的要求,因此需要编译安装较新版本的lua环境,然后才能编译安装HAProxy
参考链接:http://www.lua.org/start.html
#当前系统版本
[root@centos7 ~]#lua -v
安装lua 最新版
curl -R -O http://www.lua.org/ftp/lua-5.4.4.tar.gz
在HAProxy官网安装最新版
Lua: getting started
编译
HAPROXY_VERSION=2.6.6
HAPROXY_FILE=haproxy-${HAPROXY_VERSION}.tar.gz
#HAPROXY_FILE=haproxy-2.2.12.tar.gz
LUA_VERSION=5.4.4
LUA_FILE=lua-${LUA_VERSION}.tar.gz
#LUA_FILE=lua-5.4.3.tar.gz
HAPROXY_INSTALL_DIR=/apps/haproxySRC_DIR=/usr/local/src
CWD=`pwd`
CPUS=`lscpu |awk '/^CPU\(s\)/{print $2}'`
LOCAL_IP=$(hostname -I|awk '{print $1}')STATS_AUTH_USER=admin
STATS_AUTH_PASSWORD=123456VIP=192.168.10.100
MASTER1=192.168.10.101
MASTER2=192.168.10.102
MASTER3=192.168.10.103. /etc/os-releasecolor () {RES_COL=60MOVE_TO_COL="echo -en \\033[${RES_COL}G"SETCOLOR_SUCCESS="echo -en \\033[1;32m"SETCOLOR_FAILURE="echo -en \\033[1;31m"SETCOLOR_WARNING="echo -en \\033[1;33m"SETCOLOR_NORMAL="echo -en \E[0m"echo -n "$1" && $MOVE_TO_COLecho -n "["if [ $2 = "success" -o $2 = "0" ] ;then${SETCOLOR_SUCCESS}echo -n $" OK " elif [ $2 = "failure" -o $2 = "1" ] ;then ${SETCOLOR_FAILURE}echo -n $"FAILED"else${SETCOLOR_WARNING}echo -n $"WARNING"fi${SETCOLOR_NORMAL}echo -n "]"echo
}check_file (){if [ ! -e ${LUA_FILE} ];thencolor "缺少${LUA_FILE}文件!" 1exitelif [ ! -e ${HAPROXY_FILE} ];thencolor "缺少${HAPROXY_FILE}文件!" 1exitelsecolor "相关文件已准备!" 0fi
}install_packs () {if [ $ID = "centos" -o $ID = "rocky" ];thenyum -y install gcc make gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel libtermcap-devel ncurses-devel libevent-devel readline-devel elif [ $ID = "ubuntu" ];thenapt update apt -y install gcc make openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev libreadline-dev libsystemd-dev elsecolor "不支持此操作系统!" 1fi[ $? -eq 0 ] || { color '安装软件包失败,退出!' 1; exit; }
}install_lua () {tar xf ${LUA_FILE} -C ${SRC_DIR}LUA_DIR=${LUA_FILE%.tar*}cd ${SRC_DIR}/${LUA_DIR}make all test
}install_haproxy(){cd ${CWD}tar xf ${HAPROXY_FILE} -C ${SRC_DIR}HAPROXY_DIR=${HAPROXY_FILE%.tar*}cd ${SRC_DIR}/${HAPROXY_DIR}make -j ${CPUS} ARCH=x86_64 TARGET=linux-glibc USE_PROMEX=1 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_CPU_AFFINITY=1 USE_LUA=1 LUA_INC=${SRC_DIR}/${LUA_DIR}/src/ LUA_LIB=${SRC_DIR}/${LUA_DIR}/src/ PREFIX=${HAPROXY_INSTALL_DIR}make install PREFIX=${HAPROXY_INSTALL_DIR}[ $? -eq 0 ] && color "HAPROXY编译安装成功" 0 || { color "HAPROXY编译安装失败,退出!" 1;exit; }[ -L /usr/sbin/haproxy ] || ln -s ${HAPROXY_INSTALL_DIR}/sbin/haproxy /usr/sbin/ [ -d /etc/haproxy ] || mkdir /etc/haproxy [ -d /var/lib/haproxy/ ] || mkdir -p /var/lib/haproxy/ cat > /etc/haproxy/haproxy.cfg <<-EOF
global
maxconn 100000
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
uid 99
gid 99
daemonpidfile /var/lib/haproxy/haproxy.pid
log 127.0.0.1 local3 infodefaults
option http-keep-alive
option forwardfor
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000mslisten statsmode httpbind 0.0.0.0:9999stats enablelog globalstats uri /haproxy-statusstats auth ${STATS_AUTH_USER}:${STATS_AUTH_PASSWORD}#listen kubernetes-6443
# bind ${VIP}:6443
# mode tcp
# log global
# server ${MASTER1} ${MASTER1}:6443 check inter 3000 fall 2 rise 5
# server ${MASTER2} ${MASTER2}:6443 check inter 3000 fall 2 rise 5
# server ${MASTER3} ${MASTER2}:6443 check inter 3000 fall 2 rise 5EOFgroupadd -g 99 haproxyuseradd -u 99 -g haproxy -d /var/lib/haproxy -M -r -s /sbin/nologin haproxy
}start_haproxy () {cat > /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
EOFsystemctl daemon-reloadsystemctl enable --now haproxy systemctl is-active haproxy &> /dev/null && color 'HAPROXY安装完成!' 0 || { color 'HAPROXY 启动失败,退出!' 1; exit; }echo "-------------------------------------------------------------------"echo -e "请访问链接: \E[32;1mhttp://${LOCAL_IP}:9999/haproxy-status\E[0m"echo -e "用户和密码: \E[32;1m${STATS_AUTH_USER}/${STATS_AUTH_PASSWORD}\E[0m"
}check_file
install_packs
install_lua
install_haproxy
start_haproxy
这里o.o.o是都能连,加上ip只能指定网段链接 #端口号6666有问题,直能用国内浏览器访问
HAProxy 基于 Docker 部署
mkdir /data/haproxy/ -p
cat > /data/haproxy/haproxy.cfg
global
maxconn 100000
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
uid 99
gid 99
daemon
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 stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth admin:123456在页面执行
docker run -d --name myhaproxy -v
/data/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro -p 9999:9999 --
sysctl net.ipv4.ip_unprivileged_port_start=0 haproxy:2.6.6-alpine3.16
HAProxy 基础配置
HAProxy 的配置文件haproxy.cfg由两大部分组成,分别是global和proxies部分
global:全局配置段
进程及安全配置相关的参数
性能调整相关参数
Debug参数
proxies:代理配置段
defaults:为frontend, backend, listen提供默认配置
frontend:前端,相当于nginx中的server {}
backend:后端,相当于nginx中的upstream {}
listen:同时拥有前端和后端配置,配置简单,生产推荐使用
Global 配置参数说明
chroot #锁定运行目录
deamon #以守护进程运行
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin process 1 #socket文件,并可以通过此文件管理
user, group, uid, gid #运行haproxy的用户身份
#nbproc n #开启的haproxy worker 进程数,默认进程数是一个, nbproc从HAProxy 2.5开始不再支持
nbthread 1 #和多进程 nbproc配置互斥(版本有关,CentOS8的haproxy1.8无此问题),指定每个haproxy进程开启的线程数,默认为每个进程一个线程#如果同时启用nbproc和nbthread 会出现以下日志的错误,无法启动服务
Apr 7 14:46:23 haproxy haproxy: [ALERT] 097/144623 (1454) : config : cannot
enable multiple processes if multiple threads are configured. Please use either
nbproc or nbthread but not both.#cpu-map 1 0 #绑定haproxy worker 进程至指定CPU,将第1个worker进程绑定至0号CPU
#cpu-map 2 1 #绑定haproxy worker 进程至指定CPU,将第2个worker进程绑定至1号CPUcpu-map auto:1/1-8 0-7 #haproxy2.4中启用nbthreads,在global配置中添加此选项,可以进行线
程和CPU的绑定,nbproc选项2.5版本中将会删除,每个进程中1-8个线程分别绑定0-7号CPUmaxconn n #每个haproxy进程的最大并发连接数
maxsslconn n #每个haproxy进程ssl最大连接数,用于haproxy配置了证书的场景下
maxconnrate n #每个进程每秒创建的最大连接数量
spread-checks n #后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间,默认值0
pidfile #指定pid文件路径
log 127.0.0.1 local2 info #定义全局的syslog服务器;日志服务器需要开启UDP协议,最多可以定义两个
HAProxy日志配置
HAproxy本身不记录客户端的访问日志.此外为减少服务器负载,一般生产中HAProxy不记录日志.
也可以配置HAProxy利用rsyslog服务记录日志到指定日志文件中
开启后haprosy压力比较大
HAProxy配置 默认是不需要的
vim /etc/haproxy/haproxy.cfg #主配置文件表示记录在哪里
log 127.0.0.1 local3 info[root@ubuntu2004 ~]#vim /etc/rsyslog.conf #开启这两行
module(load="imudp")
input(type="imudp" port="514")vim /etc/rsyslog.d/haproxy.conf #加上这一项 这样就指定日志文件了
local3 info /var/log/haproxy.logsystemctl restart haproxy.service
Rsyslog配置
vim /etc/rsyslog.d/haproxy.conf #可以创建一个*。conf的文件
local3.info /var/log/haproxy.log #在里面指定一个日志目录就可以自己创建*.log
# systemctl restart rsyslog
刷新页面之后就有了
启动本地和远程日志
[root@rocky8 ~]#vim /etc/rsyslog.conf
# Provides UDP syslog reception
# for parameters see http://www.rsyslog.com/doc/imudp.html
module(load="imudp") # needs to be done just once
input(type="imudp" port="514")# Provides TCP syslog reception
# for parameters see http://www.rsyslog.com/doc/imtcp.html
*********************************
# Save boot messages also to boot.log
local7.* /var/log/boot.log
local3.info /var/log/haproxy.log #可以在这里加一行指定日志文件,123数是可以自己改的只要本机不重就好# ### sample forwarding rule ###
[root@rocky8 ~]#systemctl restart rsyslog.service 两边重启下
[root@ubuntu2004 rsyslog.d]#systemctl restart haproxy.service
刷一下,列: 但是这样本机远程只能记录一个
Proxies 配置
官方文档:http://cbonte.github.io/haproxy-dconv/2.6/configuration.html#4
- defaults [<name>] #默认代理配置项,针对以下的frontend、backend和listen生效,可以多个name也可以没有name
- frontend <name> #前端servername,类似于Nginx的一个虚拟主机 server和LVS服务集群。
- backend <name> #后端服务器组,等于nginx的upstream和LVS中的RS服务器
- listen <name> #将frontend和backend合并在一起配置,相对于frontend和backend配置更简洁,生产常用
注意:name字段只能使用大小写字母,数字,‘-’(dash),'_‘(underscore),'.' (dot)和 ':'(colon),并且严格区分大小写
Proxies配置-defaults
defaults 配置参数:
- option redispatch #当server Id对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发
- option abortonclose #当服务器负载很高时,自动结束掉当前队列处理比较久的连接,针对业务情况选择开启
- option http-keep-alive #开启与客户端的会话保持
- option forwardfor #透传客户端真实IP至后端web服务器
- mode http|tcp #设置默认工作类型,使用TCP服务器性能更好,减少压力
- timeout http-keep-alive 120s #session 会话保持超时时间,此时间段内会转发到相同的后端服务器
- timeout connect 120s #客户端请求从haproxy到后端server最长连接等待时间(TCP连接之前),默认单位ms
- timeout server 600s #客户端请求从haproxy到后端服务端的请求处理超时时长(TCP连接之后),默认单位ms,如果超时,会出现502错误,此值建议设置较大些,防止出现502错误
- timeout client 600s #设置haproxy与客户端的最长非活动时间,默认单位ms,建议和timeoutserver相同
- timeout check 5s #对后端服务器的默认检测超时时间
- default-server inter 1000 weight 3 #指定后端服务器的默认设置
Proxies配置-listen 简化配置
使用listen替换 frontend和backend的配置方式,可以简化设置,常用于TCP协议的应用
vim /etc/sysconfig/network-scripts/ifcfg-eth0
[root@centos7 ~]# systemctl restart network
把网卡改成桥接
配置
在centos7上做各客户端 指定DNS为hapoxy IP,自己地址也做成172.20.0网段
10.0.0.106,做DSN
10.0.0.101,10.0.0.102 做nginx
[root@ubuntu2004 ~]#vim /var/www/html/index.nginx-debian.html 在两个里面写上东西
访问查看下
大概格式
nginx 格式upstream http {server 1;server 2;
}
server {listen 80;proxy_pass http://http
}hproxy 格式listen http_m50_80 #业务名字bind 172.20.0.100:80 #调度那里去server web01 10.0.0.101:80server web02 10.0.0.102:80
在100上创建eth1做172.20.0.* 找个访问不通的sudo netplan apply修改好网络后重启及haproxy
在106上把DNS改一下
[root@ubuntu2004 ~]#rndc reload 加载一下DNS
server reload successful
自己测一下
[root@centos7 ~]# cat /etc/resolv.conf #把本机哪行删除就可以正常访问了
# Generated by NetworkManager
search wang.com
nameserver 172.20.0.1
nameserver 172.20.0.222
[root@centos7 ~]# vim /etc/resolv.conf
[root@centos7 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
search wang.com
nameserver 172.20.0.222
[root@ubuntu2004 ~]#apt -y install apache2
[root@ubuntu2004 ~]#systemctl restart apache2.service
[root@ubuntu2004 ~]#echo 10.0.0.101 > /var/www/html/index.html
[root@ubuntu2004 ~]#systemctl restart apache2.service
[root@centos7 ~]# yum install httpd
[root@centos7 ~]# vim /etc/hosts
172.20.0.112 www.wang.org[root@centos7 ~]# systemctl restart httpd.service
[root@centos7 ~]# curl www.wang.org
10.0.0.102
Proxies配置-frontend
bind: #指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口,可同时用于listen字段中
#格式:
bind [<address>]:<port_range> [, ...] [param*]#注意:如果需要绑定在非本机的IP,需要开启内核参数:net.ipv4.ip_nonlocal_bind=1
backlog <backlog> #针对所有server配置,当前端服务器的连接数达到上限后的后援队列长度,注意:不支持backend
范例:
frontend http_proxy #监听http的多个IP的多个端口和sock文件bind :80,:443,:8801-8810bind 10.0.0.1:10080,10.0.0.1:10443bind /var/run/ssl-frontend.sock user root mode 600 accept-proxyfrontend http_https_proxy #https监听bind :80bind :443 ssl crt /etc/haproxy/site.pem #公钥和私钥公共文件frontend http_https_proxy_explicit #监听ipv6、ipv4和unix sock文件bind ipv6@:80bind ipv4@public_ssl:443 ssl crt /etc/haproxy/site.pembind unix@ssl-frontend.sock user root mode 600 accept-proxylisten external_bind_app1 #监听file descriptorbind "fd@${FD_APP1}"
生产示例:
frontend wang_web_port #建议采用后面形式命名:业务-服务-端口号bind :80,:8080bind 10.0.0.7:10080,:8801-8810,10.0.0.17:9001-9010mode http|tcp #指定负载协议类型use_backend <backend_name> #调用的后端服务器组名称
Proxies配置-backend
定义一组后端服务器,backend服务器将被frontend进行调用。
注意: backend 的名称必须唯一,并且必须在listen或frontend中事先定义才可以使用,否则服务无法启动
mode http|tcp #指定负载协议类型,和对应的frontend必须一致
option #配置选项
server #定义后端real server,必须指定IP和端口
注意:option后面加 httpchk,smtpchk,mysql-check,pgsql-check,ssl-hello-chk方法,可用于实现更多应用层检测功能。
server 配置 各种功能 总结
#针对一个server配置check #对指定real进行健康状态检查,如果不加此设置,默认不开启检查,只有check后面没
有其它配置也可以启用检查功能#默认对相应的后端服务器IP和端口,利用TCP连接进行周期性健康性检查,注意必须指定
端口才能实现健康性检查
addr <IP> #可指定的健康状态监测IP,可以是专门的数据网段,减少业务网络的流量
port <num> #指定的健康状态监测端口
inter <num> #健康状态检查间隔时间,默认2000 ms
fall <num> #后端服务器从线上转为线下的检查的连续失效次数,默认为3
rise <num> #后端服务器从下线恢复上线的检查的连续有效次数,默认为2
weight <weight> #默认为1,最大值为256,0(状态为蓝色)表示不参与负载均衡,但仍接受持久连接backup #将后端服务器标记为备份状态,只在所有非备份主机down机时提供服务,类似Sorry Server
disabled #将后端服务器标记为不可用状态,即维护状态,除了持久模式,将不再接受连接,状态为深黄色,优雅下线,不再接受新用户的请求
maxconn <maxconn> #当前后端server的最大并发连接数,放在,放在server 指令后面
redir http://www.baidu.com #将请求临时(302)重定向至其它URL,只适用于http模式,放在
server 指令后面
backup 当主机挂掉以后,才启用
listen www.wang.org_nginx
bind 172.20.0.112:80
balance source
hash-type consistent
server 10.0.0.101 10.0.0.101 weight 1 check addr 10.0.0.101 port 80
server 10.0.0.102 10.0.0.102 weight 1 check addr 10.0.0.102 port 80
redirect 配置
#注意:此指令和redir功能相似,但不属于server指令后面,是独立存放在listen,frontend,backend语句块redirect prefix http://www.baidu.com/ #将请求临时(302)重定向至其它URL,只适用于http模式
和上面的作用一样,都访问。不过他可以多加backend,更多访问需求
这时候状态页就分两个了,一个 frontend的一个backend的
一多个frontend对一个backend
一个frontebd对多个backend,feontend写几调度几
使用子配置文件保存配置
当业务众多时,将所有配置都放在一个配置文件中,会造成维护困难。可以考虑按业务分类,将配置信息拆分,放在不同的子配置文件中,从而达到方便维护的目的。
注意: 子配置文件的文件后缀必须为.cfg
#创建子配置目录
[root@centos7 ~]#mkdir /etc/haproxy/conf.d/#添加子配置目录到unit文件中
[root@centos7 ~]#vim /lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target[Service]
#修改下面两行 第一行加的是语法检查路径 ,第二行是指定路径
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /var/lib/haproxy/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID [Install]
WantedBy=multi-user.target#创建子配置文件,注意:必须为cfg后缀非.开头的配置文件
[root@centos7 ~]#vim /etc/haproxy/conf.d/test.cfg
listen WEB_PORT_80bind 10.0.0.7:80mode httpbalance roundrobinserver web1 10.0.0.17:80 check inter 3000 fall 2 rise 5server web2 10.0.0.27:80 check inter 3000 fall 2 rise 5[root@centos7 ~]#systemctl daemon-reload
[root@centos7 ~]#systemctl restart haproxy
就是把主配置文件的东西移到指定配置文件 ,也可以根据业务写,一个业务一个
HAProxy 调度算法
HAProxy通过固定参数 balance 指明对后端服务器的调度算法,该参数可以配置在listen或backend选项中。
HAProxy的调度算法分为静态和动态调度算法,但是有些算法可以根据参数在静态和动态算法中相互转换。
官方文档:http://cbonte.github.io/haproxy-dconv/2.4/configuration.html#4-balance
静态算法
静态算法:按照事先定义好的规则轮询进行调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时动态修改权重(只能为0和1,不支持其它值)或者修改后不生效,如果需要修改只能靠重启HAProxy生效。
Socat 工具 不用修改文件通过命令就可以做到实现脚本的批量修改
不用修改文件通过命令就可以做到实现脚本的批量修改,而不是通过传统方法重启服务了
对服务器动态权重和其它状态可以利用 socat工具进行调整,Socat 是 Linux 下的一个多功能的网络工具,名字来由是Socket CAT,相当于netCAT的增强版.Socat 的主要特点就是在两个数据流之间建立双向通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、Socket文件等
范例:利用工具socat 对服务器动态权重调整
#安装socat
[root@ubuntu1804 ~]#apt -y install socat
[root@centos ~]#yum -y install socat
#查看帮助
[root@centos7 ~]#socat -h
[root@centos7 ~]#echo "help" | socat stdio /var/lib/haproxy/haproxy.sock
可以查看当前服务的版本状态
#获取当前连接数
[root@haproxy ~]#echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock | awk '/CurrConns/{print $2}'
#set,修改权重 get查询权重
查看服务器的状态信息
[root@centos7 ~]#echo "show servers state" | socat stdio/var/lib/haproxy/haproxy.sock#修改weight,注意只针对单进程有效 #set,修改权重 get查询权重
[root@centos7 ~]#echo "set weight wang-test-80/web2 2" | socat stdio
/var/lib/haproxy/haproxy.sock
[root@centos7 ~]#echo "get weight wang-test-80/web2" | socat stdio
/var/lib/haproxy/haproxy.sock
2 (initial 3)#将后端服务器禁用,注意只针对单进程有效
[root@centos7 ~]#echo "disable server www.wang.org_nginx/10.0.0101" | socat stdio
/var/lib/haproxy/haproxy.sock#启用后端服务器
[root@centos7 ~]#echo "enable server wang-test-80/web2" | socat stdio
/var/lib/haproxy/haproxy.sock#将后端服务器软下线,即weight设为0
[root@centos7 ~]#echo "set weight wang-test-80/web1 0" | socat stdio
/var/lib/haproxy/haproxy.sock#针对haproxy的多进程,将后端服务器禁用
[root@centos7 ~]#vim /etc/haproxy/haproxy.cfg
......
stats socket /var/lib/haproxy/haproxy1.sock mode 600 level admin process 1 #绑定第
1个进程和socket文件
stats socket /var/lib/haproxy/haproxy2.sock mode 600 level admin process 2 #绑定第
2个进程和socket文件
nbproc 2#如果静态算法,如:static-rr,可以更改weight为0或1,但不支持动态更改weight为其它值,否则会提
示下面信息
[root@centos7 ~]#echo "set weight wang-test-80/web1 0" | socat stdio
/var/lib/haproxy/haproxy.sock
[root@centos7 ~]#echo "set weight wang-test-80/web1 1" | socat stdio
/var/lib/haproxy/haproxy.sock
[root@centos7 ~]#echo "set weight wang-test-80/web1 2" | socat stdio
/var/lib/haproxy/haproxy.sock
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.#新的写法
#相当于disable server
[root@ubuntu2004 ~]#echo "set server www.wang.org_nginx/web1 state maint" |
socat stdio /var/lib/haproxy/haproxy.sock
#相当于enable server
[root@ubuntu2004 ~]#echo "set server www.wang.org_nginx/web1 state ready" |
socat stdio /var/lib/haproxy/haproxy.sock[root@ubuntu2004 ~]#echo "set server www.wang.org_nginx/web1 state drain" |
socat stdio /var/lib/haproxy/haproxy.sock
static-rr 算法 基于权重的轮询调度
static-rr:基于权重的轮询调度,不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的 wrr #weight 权重
权重改成别的需要在文件里该·切重启
bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010
mode http
log global
balance static-rr #加上他成为静态的算法
server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5
server web2 10.0.0.27:80 weight 2 check inter 3000 fall 2 rise 5
范例:调整权重
[root@haproxy ~]#echo "set weight www.wang.org_nginx/10.0.0.101 0" | socat stdio
/var/lib/haproxy/haproxy.sock[root@haproxy ~]#echo "get weight www.wang.org_nginx/10.0.0.101" | socat stdio
/var/lib/haproxy/haproxy.sock
0 (initial 3)[root@haproxy ~]#echo "set weight www.wang.org_nginx/10.0.0.101 1" | socat stdio /var/lib/haproxy/haproxy.sock
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.[root@haproxy ~]#echo "set weight www.wang.org_nginx/10.0.0.101 100%" | socat
stdio /var/lib/haproxy/haproxy.sock
first 算法 根据服务器在列表中的位置,自上而下进行调度
first:根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少
不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效
first 优先连接第一个,第一个连接满了则第二。#maxconn 连接上线
listen web_host
bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010
mode http
log global
balance first #maxconn 连接上线
server web1 10.0.0.17:80 maxconn 2 weight 1 check inter 3000 fall 2 rise 5
server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
动态算法
动态算法:基于后端服务器状态进行调度适当调整,新请求将优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启。
roundrobin 算法
roundrobin:基于权重的轮询动态调度算法,支持权重的运行时调整,不同于lvs中的rr轮训模式,
HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),其每个后端backend中最多支持4095个real server,支持对real server权重动态调整,roundrobin为默认调度算法,此算法使用广泛
listen www.wang.org_nginx
balance roundrobin
bind 172.20.0.112:80
server 10.0.0.101 10.0.0.101 weight 1
server 10.0.0.102 10.0.0.102:80 weight动态算法修改权重
[root@ubuntu2004 ~]#echo "set weight www.wang.org_nginx/10.0.0.101 3" | socat stdio /var/lib/haproxy/haproxy.sock
[root@ubuntu2004 ~]#echo "get weight www.wang.org_nginx/10.0.0.101 3" | socat stdio /var/lib/haproxy/haproxy.sock
3 (initial 1)
leastconn 算法 前连接最少的后服务器而非权重进行优先调度(新客户端连接)
leastconn 加权的最少连接的动态,支持权重的运行时调整和慢启动,即根据当前连接最少的后服务器而非权重进行优先调度(新客户端连接),比较适合长连接的场景使用,比如:MySQL等场景。
listen www.wang.org_nginx
balance leastconn
bind 172.20.0.112:80
server 10.0.0.101 10.0.0.101 weight 1
server 10.0.0.102 10.0.0.102:80 weight
random 算法 基于随机数作为一致性hash的key,随机负载平衡
在1.9版本开始增加 random的负载平衡算法,其基于随机数作为一致性hash的key,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用,支持weight的动态调整,weight较大的主机有更大概率获取新请求
listen www.wang.org_nginx
balance random
bind 172.20.0.112:80
server 10.0.0.101 10.0.0.101 weight 1
server 10.0.0.102 10.0.0.102:80 weight
其他算法 其它算法即可作为静态算法,又可以通过选项成为动态算法
source 算法
源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type选项进行更改
这个算法一般是在不插入Cookie的TCP模式下使用,也可给不支持会话cookie的客户提供会话粘性,适用于需要session会话保持但不支持cookie和缓存的场景
源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash
map-base 取模法
map-based:取模法,对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法
所谓取模运算,就是计算两个数相除之后的余数,10%7=3, 7%4=3
map-based算法:基于权重取模,hash(source_ip)%所有后端服务器相加的总权重
取模法配置示例:
listen web_host
bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010
mode tcp
log global
balance source
hash-type map-based
server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 3
server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 3#不支持动态调整权重值
[root@haproxy ~]#echo "set weight web_host/10.0.0.27 10" | socat stdio
/var/lib/haproxy/haproxy.sock
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.#只能动态上线和下线
[root@haproxy ~]#echo "set weight web_host/10.0.0.27 0" | socat stdio
/var/lib/haproxy/haproxy.sock
[root@haproxy conf.d]#echo "get weight web_host/10.0.0.27" | socat stdio
/var/lib/haproxy/haproxy.sock
0 (initial 1)
一致性 hash
一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动,
hash(o)mod n ,该hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持慢启动
算法:
1、key1=hash(source_ip)%(2^32) [0---4294967295]
2、keyA=hash(后端服务器虚拟ip)%(2^32)
3、将key1和keyA都放在hash环上,将用户请求调度到离key1最近的keyA对应的后端服务器
hash环偏斜问题
增加虚拟服务器IP数量,比如:一个后端服务器根据权重为1生成1000个虚拟IP,再hash。而后端服务器权重为2则生成2000的虚拟IP,再进行hash运算,最终在hash环上生成3000个节点,从而解决hash环偏斜问题
一致性hash配置示例 \ #默认静态算法基于取模的方法,加上他改为动态算法
listen www.wang.org_nginx
balance source
hash-type consistent #默认静态算法基于取模的方法,加上他改为动态算法
bind 172.20.0.112:80
server 10.0.0.101 10.0.0.101 weight 1
server 10.0.0.102 10.0.0.102:80 weight 1
uri 算法 对总权重进行取模后,根据最终结果将请求转发到后端指定服务器
基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后,根据最终结果将请求转发到后端指定服务器,适用于后端是缓存服务器场景,默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。
注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp
uri 取模法配置示例
listen web_host
bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010
mode http #可任不写,不写是默认值http
log global #开启记录日志功能
balance urihash-type consistent #可以加可以不加,加则动,不加则静态
server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5
server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
url_param 算法 根据uip来做调度的依据
url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server,如果无没key,将按roundrobin算法
#假设:
url = http://www.wang.com/foo/bar/index.php?key=value
#则:
host = "www.wang.com"
url_param = "key=value"
listen www.wang.org_nginx
bind 172.20.0.112:80
balance url_param userid #根据uip来做调度的依据
hash-type consistent
server 10.0.0.101 10.0.0.101 weight 1
server 10.0.0.102 10.0.0.102 weight 1
userid 等于的数不同调度的值不懂 (值随机)
hdr 算法 针对不同的浏览器进行调度
针对用户每个http头部(header)请求中的指定信息做hash,此处由 name 指定的http首部将会被取出并做hash计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度
针对不同的浏览器进行调度
listen web_host
bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010
mode http
log global
balance hdr(User-Agent) # 针对不同的浏览器进行调度
#balance hdr(host)
server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5
server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
算法总结
#静态
static-rr--------->tcp/http
first------------->tcp/http#动态
roundrobin-------->tcp/http
leastconn--------->tcp/http
random------------>tcp/http#以下静态和动态取决于hash_type是否consistent
source------------>tcp/http
Uri--------------->http
url_param--------->http
hdr--------------->http
rdp-cookie-------->tcp#各种算法使用场景
first #使用较少static-rr #做了session共享的 web 集群
roundrobin
randomleastconn #数据库
source #基于客户端公网 IP 的会话保持Uri--------------->http #缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯
url_param--------->http #可以实现session保持hdr #基于客户端请求报文头部做下一步处理
rdp-cookie #基于Windows主机,很少使用
HAProxy 高级功能
基于 Cookie 的会话保持
cookie value:为当前server指定cookie值,实现基于cookie的会话黏性,相对于基于 source 地址
hash 调度算法对客户端的粒度更精准,但同时也加重了haproxy负载,目前此模式使用较少, 已经被session共享服务器代替
注意:不支持 tcp mode,使用 http mode
name: #cookie 的 key名称,用于实现持久连接
insert: #插入新的cookie,默认不插入cookie
indirect: #如果客户端已经有cookie,则不会再发送cookie信息
nocache: #当client和hapoxy之间有缓存服务器(如:CDN)时,不允许中间缓存器缓存cookie,因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器
WEBSRV这里叫什么都行 需要在server后米加上值
状态页配置项
stats enable #基于默认的参数启用stats page
stats hide-version #将状态页中haproxy版本隐藏
stats refresh <delay> #设定自动刷新时间间隔,默认不自动刷新,以秒为单位
stats uri <prefix> #自定义stats page uri,默认值:/haproxy?stats
stats realm <realm> #账户认证时的提示信息,示例:stats realm HAProxy\ Statistics
stats auth <user>:<passwd> #认证时的账号和密码,可定义多个用户,每行指定一个用户.默认:noauthentication
stats admin { if | unless } <cond> #启用stats page中的管理功能
启用状态页示例
listen haproxy-status
bind :9999
stats enable
#stats hide-version
stats uri /haproxy-status #自定义stats page uri
stats realm HAProxy\ Stats\ Page #账户认证时的提示信息
stats auth haadmin:123456 #支持多个用户
stats auth admin:123456
#stats refresh 30
stats admin if TRUE #开启管理功能,基于安全原因,不建议开启
登录状态页说明
pid = 27134 (process #1, nbproc = 1, nbthread = 1) #pid为当前pid号,process为当前进程号,nbproc和nbthread为一共多少进程和每个进程多少个线程
uptime = 0d 0h00m04s #启动了多长时间
system limits: memmax = unlimited; ulimit-n = 200029 #系统资源限制:内存/最大打开文数/
maxsock = 200029; maxconn = 100000; maxpipes = 0 #最大socket连接数/单进程最大连数/最大管道数maxpipes
current conns = 2; current pipes = 0/0; conn rate = 2/sec; bit rate = 0.000 kbps
#当前连接数/当前管道数/当前连接速率
Running tasks: 1/14; 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服务器的健康性检查
他是在页面取一行,用的时候注意页面边没边
[root@ubuntu2004 ~]#curl -s "http://admin:123456@10.0.0.100:9999/haproxy-status" |grep -q "Statistics Report for pid"
[root@ubuntu2004 ~]#echo $?
0
IP透传
web服务器中需要记录客户端的真实IP地址,用于做访问统计、安全防护、行为分析、区域排行等场
Layer 4 与 Layer 7
- 四层:IP+PORT转发
- 七层:协议+内容交换
四层负载
在LVS 传统的四层负载设备中,把client发送的报文目标地址(原来是负载均衡设备的IP地址),根据均衡设备设置的选择web服务器的规则选择对应的web服务器IP地址,这样client就可以直接跟此服务器建立TCP连接并发送数据,而四层负载自身不参与建立连接
而和LVS不同,haproxy是伪四层负载均衡,因为haproxy 需要分别和前端客户端及后端服务器建立连接
七层代理
七层负载均衡服务器起了一个反向代理服务器的作用,服务器建立一次TCP连接要三次握手,而client要访问Web Server要先与七层负载设备进行三次握手后建立TCP连接,把要访问的报文信息发送给七层负载均衡;然后七层负载均衡再根据设置的均衡规则选择特定的 Web Server,然后通过三次握手与此台Web Server建立TCP连接,然后Web Server把需要的数据发送给七层负载均衡设备,负载均衡设备再把数据发送给client;所以,七层负载均衡设备起到了代理服务器的作用,七层代理需要和Client和后端服务器分别建立连接
四层IP透传 只能通过四层代理访,本机无法访问,不推荐
server 10.0.0.101 10.0.0.101 weight 1 check addr 10.0.0.101 port 80 #添加send-proxy
#nginx 配置:在访问日志中通过变量$proxy_protocol_addr 记录透传过来的客户端IP
listen 80 proxy_protocol; #加上此项,将无法直接访问此网站,只能通过四层代理访问
vim /etc/nginx/nginx.conf
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request""$proxy_protocol_addr"' # 加上此行定义main的格式,记录变量$proxy_protocol_addr
##access_log /var/log/nginx/access.log main; 在这行后面加上mian
error_log /var/log/nginx/error.log;
nginx -tnginx -s reload
七层IP透传
当haproxy工作在七层的时候,也可以透传客户端真实IP至后端服务器
在由haproxy发往后端主机的请求报文中添加“X-Forwarded-For"首部,其值为前端客户端的地址;用于向后端主发送真实的客户端IP
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request""$proxy_add_x_forwarded_for"'
##
# Basic Settingsaccess_log /var/log/nginx/access.log main; 在这行后面加上mian
error_log /var/log/nginx/error.log;nginx -t
nginx -s reload
#nginx 日志格式:默认就支持
$proxy_add_x_forwarded_for:包括客户端IP和中间经过的所有代理的IP
$http_x_forwarded_For:只有客户端IP地址透传默认是通过vim/etc/daproxy/haproxy.cfg里默认开启的forwardfor透传的如果关闭他就不行了
报文修改
在http模式下,基于实际需求修改客户端的请求报文与响应报文,通过reqadd和reqdel在请求报文添加删除字段,通过rspadd与rspidel在响应报文中添加与删除字段。
官方文档:参看2.4的帮助文档
http://cbonte.github.io/haproxy-dconv/2.4/configuration.html#4-http-request
http://cbonte.github.io/haproxy-dconv/2.4/configuration.html#4-http-response
配置说明:
#修改请求host首部,默认host首部会保留客户端原首部haproxy不会修改
http-request set-header ***** #他也可以覆盖 列:host
#修改响应首部 有就覆盖,没有就加
http-response set-header server wangserver#添加向客户端发送的响应报文首部
http-response add-header <name> <fmt>
#删除向客户端发送的响应报文首部
http-response del-header <name> #默认 #删除后
自定义日志格式
log global 开启日志功能,默认只会在记录下面格式的日志
option httplog 可以采用 http 格式记录下来,并且可以使用相关指令将特定信息记录在haproxy的日志中 但一般不建议开启,这会加重 HAProxy 负载
log global #开启记录日志,默认不开启
option httplog #开启记录httplog日志格式选项
capture cookie <name> len <length> #捕获请求和响应报文中的 cookie及值的长度,将之记录到日志
capture request header <name> len <length> #捕获请求报文中指定的首部内容和长度并记录日志
capture response header <name> len <length> #捕获响应报文中指定的内容和长度首部并记录日志#示例:
log global
option httplog
capture request header Host len 256 记录他头部信息防止他太长
capture request header User-Agent len 512
capture request header Referer len 15
capture request header X-Forwarded-For len 15
压缩功能
对响应给客户端的报文进行压缩,以节省网络带宽,但是会占用部分CPU性能
建议在后端服务器开启压缩功能,而非在HAProxy上开启压缩
compression algo <algorithm> ... #启用http协议中的压缩机制,常用算法有
gzip,deflate
#压缩算法<algorithm>支持下面类型:
identity #debug调试使用的压缩方式
gzip #常用的压缩方式,与各浏览器兼容较好
deflate #有些浏览器不支持
raw-deflate #新式的压缩方式
compression type <mime type> ... #要压缩的文件类型
#示例:
compression algo gzip deflate
compression type text/html text/css text/plain
后端服务器健康性监测
四层健康行检测有时候不太灵敏,比如web界面打不开,但是80端口一直开着,他不会报错误
三种状态监测方式
基于四层的传输端口做状态监测,此为默认方式
基于指定 URI 做状态监测,需要访问整个页面资源,占用更多带宽
基于指定 URI 的 request 请求头部内容做状态监测,占用较少带宽,建议使用此方式
基于应用层http协议进行健康性检测
基于应用层http协议,采有不同的监测方式,对后端real server进行状态监测
注意: 此方式会导致在后端服务器生成很多的HAProxy发起的访问日志
option httpchk #启用七层健康性检测,对tcp 和 http 模式都支持,默认为:OPTIONS /HTTP/1.0 ,nginx默认不支持,apache支持此方法
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>
GET 请求比较占用资源,这里可以改成HEAD请求
GET请求
从服务器上获取资源
HEAD请求
HEAD方法与 GET 方法类似,也是请求从服务器获取资源,服务器的处理机制也是一样的,但服务器不会返回请求的实体数据,只会传回响应头,也就是资源的“元信息”。HEAD 方法可以看做是 GET 方法的一个“简化版”或者“轻量版”。因为它的响应头与 GET 完全相同,所以可以用在很多并不真正需要资源的场合,避免传输 body 数据的浪费。
配置示例
listen web_host
bind 10.0.0.7:80
mode http
balance roundrobin
#option httpchk GET /monitor/check.html #默认HTTP/1.0,如果加版本就必须加HOST
#option httpchk GET /monitor/check.html HTTP/1.0
#option httpchk GET /monitor/check.html HTTP/1.1 # 注意:HTTP/1.1强制要求必须有Host字段
option httpchk HEAD /monitor/check.html HTTP/1.1\r\nHost:\ 10.0.0.7 #使用HEAD减少网络流量
cookie SERVER-COOKIE insert indirect nocache
server web1 10.0.0.17:80 cookie web1 check inter 3000 fall 3 rise 5
server web2 10.0.0.27:80 cookie web2 check inter 3000 fall 3 rise 5#在所有后端服务建立检测页面
[root@backend ~]#mkdir /var/www/html/monitor/
[root@backend ~]#echo monitor > /var/www/html/monitor/check.html#关闭一台Backend服务器
[root@backend1 ~]#systemctl stop httpd
ACL
访问控制列表(ACL,Access Control Lists)是一种基于包过滤的访问控制技术,它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配),即对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行进一步操作,比如允许其通过或丢弃。
官方帮助:
http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#7
http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#7
定义ACL配置选项
acl <aclname> <criterion> [flags] [operator] [<value>]
acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
ACL-Name
acl image_service hdr_dom(host) -i img.wang.com
#ACL名称,可以使用大字母A-Z、小写字母a-z、数字0-9、冒号:、点.、中横线和下划线,并且严格区分大小写,比如:my_acl和My_Acl就是两个完全不同的acl
问题:如何指定访问?
-i 不许分大小写
hdr string,提取在一个HTTP请求报文的首部
hdr([<name> [,<occ>]]):完全匹配字符串,header的指定信息,<occ> 表示在多值中使用的值的现次数
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模糊匹配#示例:
hdr(<string>) 用于测试请求头部首部指定内容 就是host后面的网站名
hdr_dom(host) 请求的host名称,如 www.wang.com,m.wang.com
hdr_beg(host) 请求的host开头,如 www. img. video. download. ftp.
hdr_end(host) 请求的host结尾,如 .com .net .cn#示例:acl定义个名称为bad_agent的,匹配里面的hdr_sub(User-Agent)的文件 是否包含 curl wget件,
请求文件里面有 if 就拒绝
acl bad_agent hdr_sub(User-Agent) -i curl wget
http-request deny if bad_agent#block if bad_agent 2.1版本后不再支持,用上面替代
base : string #是自己加的,方便看
#返回第一个主机头和请求的路径部分的连接,该请求从主机名开始,并在问号之前结束,对虚拟主机有用,下面的例子中是两个#中间的内容,实际#是没有的
<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>path : string
#提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分)
<scheme>://<user>:<password>@<host>:<port>#/<path>;<params>#?<query>#<frag>
ACL匹配模式
-i 不区分大小写
-m 使用指定的pattern匹配方法
-n 不做DNS解析
-u 禁止acl重名,否则多个同名ACL匹配或关系
多个ACL的逻辑处理
与:隐式(默认)使用
或:使用“or" 或 “||"表示
否定:使用 "!" 表示#示例:
if valid_src valid_port #与关系,ACL中A和B都要满足为true,默认为与
if invalid_src || invalid_port #或,ACL中A或者B满足一个为true
if ! invalid_src #非,取反,不满足ACL才为true
ACL示例:域名匹配
www你就去17, mobile你就去27
cat /etc/haproxy/conf.d/test.cfg
frontend wang_http_port
bind 10.0.0.7:80
mode http
balance roundrobin
log global
option httplog###################### acl setting ###############################
acl pc_domain hdr_dom(host) -i www.wang.org
acl mobile_domain hdr_dom(host) -i mobile.wang.org###################### acl hosts #################################
use_backend pc_hosts if pc_domain
use_backend mobile_hosts if mobile_domain
default_backend pc_hosts #所有ACL都不匹配,则使用的默认backend###################### backend hosts #############################
backend mobile_hosts
mode http
server web1 10.0.0.17 check inter 2000 fall 3 rise 5backend pc_hosts
mode http
server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5
定义 HAProxy 错误界面
对指定的报错进行重定向,进行优雅的显示错误页面
基于自定义的错误页面文件
#自定义错误页
errorfile <code> <file>
<code> #HTTP status code.支持200, 400, 403, 405, 408, 425, 429, 500, 502,503,504
<file> #包含完整HTTP响应头的错误页文件的绝对路径。 建议后缀为".http",以和一般的html文件相区
分
#示例:
errorfile 400 /etc/haproxy/errorfiles/400badreq.http
errorfile 403 /etc/haproxy/errorfiles/403forbid.http
errorfile 503 /etc/haproxy/errorfiles/503sorry.http
不管是主配置文件还是,副配置文件,都可以,把报错及详细页面地址写上,创建文件写上内容
他这个头的话,为什么nginx不需要加,而http就需要加呢?
因为http就是个代理没有web功能
vim /etc/haproxy/haproxy.cfg
defaults
option http-keep-alive
option forwardfor
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
errorfile 503 /apps/haproxy/html/503.http报错页面
[root@centos7 ~]#vim /apps/haproxy/html/503.http
HTTP/1.1 503 Service Unavailable
Content-Type:text/html;charset=utf-8<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>报错页面</title>
</head>
<body>
<center><h1>网站维护中......请稍候再试</h1></center>
<center><h2>联系电话:400-123-4567</h2></center>
<center><h3>503 Service Unavailable</h3></center>
</body>
HAProxy Https 实现
haproxy支持https,基于性能考虑,证书是在后端服务器比如nginx上实现,即用户到haproxy利用tcp模式再到后端服务器
CA_SUBJECT="/O=wang/CN=ca.wang.org"
SUBJECT="/C=CN/ST=henan/L=zhengzhou/O=wang/CN=www.wang.org"
SERIAL=34
EXPIRE=202002
FILE=wang.orgopenssl req -x509 -newkey rsa:2048 -subj $CA_SUBJECT -keyout ca.key -nodes -days 202002 -out ca.crtopenssl req -newkey rsa:2048 -nodes -keyout ${FILE}.key -subj $SUBJECT -out ${FILE}.csropenssl x509 -req -in ${FILE}.csr -CA ca.crt -CAkey ca.key -set_serial $SERIAL -days $EXPIRE -out ${FILE}.crtchmod 600 ${FILE}.key ca.key
指定公网地址,用ssl加密 证书文件
redirect scheme https if !{ ssl_fc } #这行的意思大概就是把不是s的装换成s
满足条件跳转https,不满足跳别的