编辑
2022-04-19
haproxy
00

目录

一、haproxy配置
1、脚本安装haproxy
2、 Global配置
3、HAProxy日志配置
4、Proxies 配置
5、使用子配置文件保存配置
6、利用haproxy代理本机docker容器两个web页面
7、静态调度算法
8、动态调度算法
9、其他算法
10、算法总结
二、haproxy部分案例
11、基于 Cookie 的会话保持
12、HAProxy 状态页
13、 后端服务器健康性检查
14、ACL配置
15、多虚拟主机配置实例,减少公网IP的使用
16、动静分离
17、HAProxy Https 实现

一、haproxy配置

1、脚本安装haproxy
sh
---需先准备lua和haproxy包--- #!/bin/bash HAPROXY_VERSION=2.6.7 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/haproxy SRC_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=123456 VIP=192.168.10.100 MASTER1=192.168.10.101 MASTER2=192.168.10.102 MASTER3=192.168.10.103 . /etc/os-release color () { RES_COL=60 MOVE_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_COL echo -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} ];then color "缺少${LUA_FILE}文件!" 1 exit elif [ ! -e ${HAPROXY_FILE} ];then color "缺少${HAPROXY_FILE}文件!" 1 exit else color "相关文件已准备!" 0 fi } install_haproxy(){ if [ $ID = "centos" -o $ID = "rocky" ];then yum -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" ];then apt update apt -y install gcc make openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev libreadline-dev libsystemd-dev else color "不支持此操作系统!" 1 fi [ $? -eq 0 ] || { color 'HAPROXY 启动失败,退出!' 1; exit; } tar xf ${LUA_FILE} -C ${SRC_DIR} LUA_DIR=${LUA_FILE%.tar*} cd ${SRC_DIR}/${LUA_DIR} make all test 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_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/ &> /dev/null [ -d /etc/haproxy ] || mkdir /etc/haproxy &> /dev/null [ -d /var/lib/haproxy/ ] || mkdir -p /var/lib/haproxy/ &> /dev/null cat > /etc/haproxy/haproxy.cfg <<-EOF 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 ${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 5 EOF #echo "PATH=${HAPROXY_INSTALL_DIR}/sbin:${PATH}" > /etc/profile.d/haproxy.sh groupadd -g 99 haproxy useradd -u 99 -g haproxy -d /var/lib/haproxy -M -r -s /sbin/nologin 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 EOF systemctl daemon-reload systemctl 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" } main(){ check_file install_haproxy } main
2、 Global配置
sh
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从HAProxy2.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号CPU cpu-map auto:1/1-8 0-7 #haproxy2.4中启用nbthreads,在global配置中添加此选项,可以进行线程和CPU的绑定,nbproc选项2.5版本中将会删除,每个进程中1-8个线程分别绑定0-7号CPU maxconn 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协议,最多可以定 义两个
3、HAProxy日志配置

HAProxy配置

sh
#在global配置项定义: log 127.0.0.1 local{1-7} info #基于syslog记录日志到指定设备,级别有(err、warning、info、debug) listen web_port bind 127.0.0.1:80 mode http log global #开启当前web_port的日志功能,默认不记录日志 server web1 127.0.0.1:8080 check inter 3000 fall 2 rise 5 # systemctl restart haproxy

Rsyslog配置

sh
vim /etc/rsyslog.conf $ModLoad imudp $UDPServerRun 514 ...... local3.* /var/log/haproxy.log ...... # systemctl restart rsyslog
4、Proxies 配置
sh
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

sh
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,建议和timeout server相同 timeout check 5s #对后端服务器的默认检测超时时间 default-server inter 1000 weight 3 #指定后端服务器的默认设置

Proxies配置-listen 简化配置

sh
#官网业务访问入口 listen WEB_PORT_80 bind 192.168.10.100:80 mode http option forwardfor server web1 10.0.0.17:8080 check inter 3000 fall 3 rise 5 server web2 10.0.0.27:8080 check inter 3000 fall 3 rise 5 #检查语法 [root@ubuntu2004 ~]#haproxy -c -f /etc/haproxy/haproxy.cfg Configuration file is valid
5、使用子配置文件保存配置

当业务众多时,将所有配置都放在一个配置文件中,会造成维护困难。可以考虑按业务分类,将配置信 息拆分,放在不同的子配置文件中,从而达到方便维护的目的。

注意: 子配置文件的文件后缀必须为.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_80 bind 10.0.0.7:80 mode http balance roundrobin server web1 10.0.0.17:80 check inter 3000 fall 2 rise 5 server web2 10.0.0.27:80 check inter 3000 fall 2 rise 5 [root@centos7 ~]#systemctl daemon-reload [root@centos7 ~]#systemctl restart haproxy
6、利用haproxy代理本机docker容器两个web页面
sh
#启动两个容器 docker run -d -v /data/nginx:/data/html --name n1 xiaowei200957079/nginx:v1.22-1 docker run -d -v /data/nginx1:/data/html --name n2 xiaowei200957079/nginx:v1.22-1 #两个web容器的主页面 [root@rocky7 nginx]#cat /data/nginx/index.html /data/nginx1/index.html <h1> welcome to docker website first</h1> <h1> welcome to docker website second</h1> #修改haproxy的listen配置 listen web-nginx mode http bind 10.0.0.140:80 server web01 172.17.0.2:80 check server web02 172.17.0.3:80 check #语法检查命令 [root@rocky7 nginx]#haproxy -c -f /etc/haproxy/haproxy.cfg Configuration file is valid
7、静态调度算法

静态算法:按照事先定义好的规则轮询进行调度,不关心后端服务器的当前负载、连接数和响应速度 等,且无法实时动态修改权重(只能为0和1,不支持其它值)或者修改后不生效,如果需要修改只能靠重启HAProxy生效。

  • Socat 工具,需安装,yum -y install socat
sh
利用工具socat 对服务器动态权重调整 echo "help" | socat stdio /var/lib/haproxy/haproxy.sock #可以用于实现Zabbix监控 [root@centos7 ~]#echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock Name: HAProxy Version: 2.1.3 Release_date: 2020/02/12 Nbthread: 4 Nbproc: 1 Process_num: 1 Pid: 2279 Uptime: 0d 0h46m07s Uptime_sec: 2767 Memmax_MB: 0 PoolAlloc_MB: 0 PoolUsed_MB: 0 PoolFailed: 0 Ulimit-n: 200041 Maxsock: 200041 Maxconn: 100000 Hard_maxconn: 100000 CurrConns: 0 CumConns: 1 CumReq: 1 MaxSslConns: 0 CurrSslConns: 0 CumSslConns: 0 Maxpipes: 0 PipesUsed: 0 PipesFree: 0 ConnRate: 0 ConnRateLimit: 0 MaxConnRate: 0 SessRate: 0 SessRateLimit: 0 MaxSessRate: 0 SslRate: 0 SslRateLimit: 0 MaxSslRate: 0 SslFrontendKeyRate: 0 SslFrontendMaxKeyRate: 0 SslFrontendSessionReuse_pct: 0 SslBackendKeyRate: 0 SslBackendMaxKeyRate: 0 SslCacheLookups: 0 SslCacheMisses: 0 CompressBpsIn: 0 CompressBpsOut: 0 CompressBpsRateLim: 0 ZlibMemUsage: 0 MaxZlibMemUsage: 0 Tasks: 19 Run_queue: 1 Idle_pct: 100 node: centos7.wangxiaochun.com Stopping: 0 Jobs: 7 Unstoppable Jobs: 0 Listeners: 6 ActivePeers: 0 ConnectedPeers: 0 DroppedLogs: 0 BusyPolling: 0 FailedResolutions: 0 TotalBytesOut: 0 BytesOutRate: 0 DebugCommandsIssued: 0 #查看服务器权重,这里的zhang-test-80是listen的名称,web2是server的名称 echo "get weight zhang-test-80/web2" | socat stdio /var/lib/haproxy/haproxy.sock #修改服务器权重 echo "set weight zhang-test-80/web2 2" | socat stdio /var/lib/haproxy/haproxy.sock #新的写法 #相当于disable server [root@ubuntu2004 ~]#echo "set server www.zhang.org_nginx/web1 state maint" | socat stdio /var/lib/haproxy/haproxy.sock #维护中 #相当于enable server [root@ubuntu2004 ~]#echo "set server www.zhang.org_nginx/web1 state ready" | socat stdio /var/lib/haproxy/haproxy.sock #上线 [root@ubuntu2004 ~]#echo "set server www.zhang.org_nginx/web1 state drain" | socat stdio /var/lib/haproxy/haproxy.sock #暂停
  • static-rr 算法
sh
static-rr:基于权重的轮询调度,不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的 wrr listen web_host 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
  • first 算法
sh
first:根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效maxconn 2 为设置最大连接数 listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode http log global balance first 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
8、动态调度算法
  • roundrobin 算法

roundrobin:基于权重的轮询动态调度算法,支持权重的运行时调整,不同于lvs中的rr轮训模式,HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),其每个后端backend中最多支 持4095个real server,支持对real server权重动态调整,roundrobin为默认调度算法,此算法使用广泛

c
listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode http log global balance roundrobin 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 #支持动态调整权重 # echo "get weight web_host/web1" | socat stdio /var/lib/haproxy/haproxy.sock 1 (initial 1) # echo "set weight web_host/web1 3" | socat stdio /var/lib/haproxy/haproxy.sock # echo "get weight web_host/web1" | socat stdio /var/lib/haproxy/haproxy.sock 3 (initial 1)
  • leastconn 算法

leastconn 加权的最少连接的动态,支持权重的运行时调整和慢启动,即根据当前连接最少的后端服务 器而非权重进行优先调度(新客户端连接),比较适合长连接的场景使用,比如:MySQL等场景。

c
listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode tcp #默认模式为http,可根据具体情况修改协议 log global balance leastconn server web1 10.0.0.17:3306 weight 1 check inter 3000 fall 2 rise 5 server web2 10.0.0.27:3306 weight 1 check inter 3000 fall 2 rise 5
  • random 算法

在1.9版本开始增加 random的负载平衡算法,其基于随机数作为一致性hash的key,随机负载平衡对于 大型服务器场或经常添加或删除服务器非常有用,支持weight的动态调整,weight较大的主机有更大概率获取新请求

c
listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode http log global balance random 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
9、其他算法
  • source 算法

源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一 个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服 务器,默认为静态方式,但是可以通过hash-type选项进行更改 这个算法一般是在不插入Cookie的TCP模式下使用,也可给不支持会话cookie的客户提供会话粘性,适 用于需要session会话保持但不支持cookie和缓存的场景 源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash

  • uri 算法

基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后,根据最终结果 将请求转发到后端指定服务器,适用于后端是缓存服务器场景,默认是静态算法,也可以通过hash-type 指定map-based和consistent,来定义使用取模法还是一致性hash。

注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp

c
#取模法配置实例: listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode http log global balance uri 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
c
#uri 一致性hash配置示例 listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode http log global balance uri hash-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 算法

url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器 总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同 一个real server,如果无没key,将按roundrobin算法

c
#url_param取模法配置示例 listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode http log global balance url_param userid #url_param hash 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一致性hash配置示例 listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode http log global balance url_param userid #对url_param的值取hash hash-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
  • hdr 算法

针对用户每个http头部(header)请求中的指定信息做hash,此处由 name 指定的http首部将会被取出并 做hash计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮 询调度。

c
#hdr取模法配置示例 #针对不同的浏览器进行调度 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 #一致性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) hash-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
  • rdp-cookie 算法

rdp-cookie对远windows远程桌面的负载,使用cookie保持会话,默认是静态,也可以通过hash-type 指定map-based和consistent,来定义使用取模法还是一致性hash。

10、算法总结
c
#静态 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 #使用较多 random leastconn #数据库 source #基于客户端公网 IP 的会话保持 Uri--------------->http #缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯 url_param--------->http #可以实现session保持 hdr #基于客户端请求报文头部做下一步处理 rdp-cookie #基于Windows主机,很少使用

二、haproxy部分案例

cookie value:为当前server指定cookie值,实现基于cookie的会话黏性,相对于基于 source 地址 hash 调度算法对客户端的粒度更精准,但同时也加重了haproxy负载,目前此模式使用较少, 已经被 session共享服务器代替

注意:不支持 tcp mode,使用 http mode

c
#配置选项 cookie name [ rewrite | insert | prefix ][ indirect ] [ nocache ][ postonly ] [ preserve ][ httponly ] [ secure ][ domain ]* [ maxidle <idle> ][ maxlife ] name: #cookie 的 key名称,用于实现持久连接 insert: #插入新的cookie,默认不插入cookie indirect: #如果客户端已经有cookie,则不会再发送cookie信息 nocache: #当client和hapoxy之间有缓存服务器(如:CDN)时,不允许中间缓存器缓存cookie,因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器 #配置实例 listen web_port bind 10.0.0.7:80 balance roundrobin mode http #不支持 tcp mode log global cookie WEBSRV insert nocache indirect server web1 10.0.0.17:80 check inter 3000 fall 2 rise 5 cookie web1 server web2 10.0.0.27:80 check inter 3000 fall 2 rise 5 cookie web2
12、HAProxy 状态页
c
#**状态页配置项** 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> #认证时的账号和密码,可定义多个用户,每行指定一个用户.默认:no authentication 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 #开启管理功能,基于安全原因,不建议开启
  • 登录状态页说明
c
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)
13、 后端服务器健康性检查
  • 三种状态监测方式
c
基于四层的传输端口做状态监测,此为默认方式 #web服务器后跟check即可实现 基于指定 URI 做状态监测,需要访问整个页面资源,占用更多带宽 #在listen 命令下添加 option httpchk 即可 基于指定 URI 的 request 请求头部内容做状态监测,占用较少带宽,建议使用此方式
  • http响应码探测,生产中使用
c
#配置实例 listen web_host bind 10.0.0.7:80 mode http balance roundrobin #option httpchk GET /monitor/check.html #默认HTTP/1.0 #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服务器查看结果即可
14、ACL配置
  • ACL-Name
markdown
acl image_service hdr_dom(host) -i img.wang.com #ACL名称,可以使用大字母A-Z、小写字母a-z、数字0-9、冒号:、点.、中横线和下划线,并且严格区分大小写,比如:my_acl和My_Acl就是两个完全不同的acl
  • ACL-criterion,定义ACL匹配规范,即:判断条件
c
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>) 用于测试请求头部首部指定内容 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) -i curl wget http-request deny if bad_agent #如果识别到的浏览器是curl和wget,那就禁止访问 #有些功能是类似的,比如以下几个都是匹配用户请求报文中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. src #源IP src_port #源PORT dst #目标IP dst_port #目标PORT #多个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 #例: listen http_80 bind 10.0.0.8:80 option httpchk HEAD /monitor/check.html HTTP/1.1\r\nHost:\ 10.0.0.8 acl bad_agent hdr_sub(User-Agent) -i curl wget acl danger_src src 10.0.0.28 httpbad_agent hdr_sub(User-Agent) || danger_src #不加||时需要满足两个条件才会拒绝,在10.0.0.28上使用curl或wget拒绝访问,加上||时变成或的关系,有一个条件满足才会拒绝访问 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
15、多虚拟主机配置实例,减少公网IP的使用
sh
frontend http_80 bind 10.0.0.7:80 mode http acl www_domain hdr_dom(host) -i www.ztunan.com acl app_domain hdr_dom(host) -i app.ztunan.com use_backend www.ztunan.com if www_domain use_backend app.ztunan.com if app_domain backend www.ztunan.com server 10.0.0.130 10.0.0.130:80 check backend app.ztunan.com server 10.0.0.133 10.0.0.133:80 check #最终实现效果,只提供一个公网地址10.0.0.7,访问www.ztunan.com时,haproxy调度到10.0.0.130,。访问app.ztunan.com时,haproxy调度到10.0.0.133.
16、动静分离
  • 基于文件后缀名实现动静分离
markdown
path : string # #提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分) <scheme>://<user>:<password>@<host>:<port>#/<path>;<params>#?<query>#<frag> path : exact string match path_beg : prefix match #请求的URL开头,如/static、/images、/img、/css path_end : suffix match #请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg path_dom : domain match path_dir : subdir match path_len : length match path_reg : regex match path_sub : substring match #实例 path_beg -i /haproxy-status/ path_end .jpg .jpeg .png .gif path_reg ^/images.*\.jpeg$ path_sub image path_dir jpegs path_dom wang #使用此配置可实现haproxy的动静分离 #例: frontend http_80 bind 10.0.0.7:80 acl acl_static path_end -i .jpg .jpeg .png .gif .txt .html mode http acl www_domain hdr_dom(host) -i www.ztunan.com acl app_domain hdr_dom(host) -i app.ztunan.com use_backend www.ztunan.com if www_domain || acl_static #当用户访问www.ztunan.com或者访问静态页面时,访问www.ztunan.com对应的10.0.0.130机器,否则访问10.0.0.133机器 use_backend app.ztunan.com if app_domain backend www.ztunan.com server 10.0.0.130 10.0.0.130:80 check backend app.ztunan.com server 10.0.0.133 10.0.0.133:80 check #实例: [root@centos7 ~]#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 acl_static path_end -i .jpg .jpeg .png .gif .css .js .html #基于文件后缀名 的ACL acl acl_php path_end -i .php ###################### acl hosts ################################# use_backend mobile_hosts if acl_static use_backend app_hosts if acl_php default_backend pc_hosts ###################### backend hosts ############################# backend mobile_hosts mode http server web1 10.0.0.17 check inter 2000 fall 3 rise 5 backend pc_hosts mode http server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5 backend app_hosts mode http server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5 #分别在后端两台主机准备相关文件 [root@centos17 ~]#ls /var/www/html index.html wang.jpg [root@centos27 ~]#cat /var/www/html/test.php <?php echo "<h1>http://10.0.0.27/test.php</h1>\n"; ?>
  • 基于访问路径实现动静分离
c
[root@centos7 ~]#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 acl_static path_beg -i /static /images /javascript #基于路径的ACL acl acl_static path_end -i .jpg .jpeg .png .gif .css .js .html .htm #ACL同名为或关系 acl acl_app path_beg -i /api ###################### acl hosts ################################# use_backend static_hosts if acl_static use_backend app_hosts if acl_app default_backend app_hosts ###################### backend hosts ############################# backend static_hosts mode http server web1 10.0.0.17 check inter 2000 fall 3 rise 5 backend app_hosts mode http server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5 #创建相关文件 [root@centos17 ~]#mkdir /var/www/html/static [root@centos17 ~]#echo 10.0.0.17 > /var/www/html/static/test.html #测试访问 [root@centos6 ~]#curl 10.0.0.7/static/test.html 10.0.0.17
17、HAProxy Https 实现
  • haproxy支持https,基于性能考虑,证书是在后端服务器比如nginx上实现,即用户到haproxy利用tcp模式 再到后端服务器
c
#示例: listen web_http bind 192.168.10.100:80 redirect scheme https if !{ ssl_fc } #如果用户访问的是80端口则自动跳转到443端口 mode http log global server web1 10.0.0.8:80 check server web2 10.0.0.18:80 check listen web_https bind 192.168.10.100:443 mode tcp log global server web1 10.0.0.8:443 check server web2 10.0.0.18:443 check
  • Haproxy 可以实现 Https 的证书安全,即从用户到haproxy为https,从haproxy到后端服务器用http通信
c
#示例: #证书制作 [root@centos7 ~]mkdir /etc/haproxy/certs/ [root@centos7 ~]cd /etc/haproxy/certs/ [root@centos7 certs]#openssl genrsa -out haproxy.key 2048 [root@centos7 certs]#openssl req -new -x509 -key haproxy.key -out haproxy.crt -subj "/CN=www.wang.org" #或者用下一条命令实现 [root@centos7 certs]#openssl req -x509 -newkey rsa:2048 -subj "/CN=www.wang.org" -keyout haproxy.key -nodes -days 365 -out haproxy.crt [root@centos7 certs]#cat haproxy.key haproxy.crt > haproxy.pem [root@centos7 certs]#openssl x509 -in haproxy.pem -noout -text #查看证书 #haproxy-Https 配置示例 cat /etc/haproxy/conf.d/test.cfg frontend wang_http_port bind 10.0.0.7:80 ###################### https setting ############################## bind 10.0.0.7:443 ssl crt /etc/haproxy/certs/haproxy.pem redirect scheme https if !{ ssl_fc } # 注意{ }内的空格 http-request set-header X-forwarded-Port %[dst_port] http-request add-header X-forwarded-Proto https if { ssl_fc } mode http balance roundrobin log global option httplog ###################### acl setting ############################### acl mobile_domain hdr_dom(host) -i mobile.wang.org ###################### acl hosts ################################# default_backend pc_hosts ################### backend hosts ################################# backend mobile_hosts mode http server web1 10.0.0.17:80 check inter 2000 fall 3 rise 5 backend pc_hosts mode http #http-request set-header X-forwarded-Port %[dst_port] 也可加在此处 #http-request add-header X-forwarded-Proto https if { ssl_fc } server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:笑一个吧~

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 本文为博主「笑一个吧~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 许可协议。转载请注明出处!