企业级反向代理 Haproxy

 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/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_packs () {
    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 '安装软件包失败,退出!' 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
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
    
	groupadd -g 99 haproxy
	useradd -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
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" 
}

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号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协议,最多可以定义两个

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.log

systemctl 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:80
   server 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-8810
    bind 10.0.0.1:10080,10.0.0.1:10443
    bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy

frontend http_https_proxy         #https监听
    bind :80
    bind :443 ssl crt /etc/haproxy/site.pem     #公钥和私钥公共文件

frontend http_https_proxy_explicit     #监听ipv6、ipv4和unix sock文件
    bind ipv6@:80
    bind ipv4@public_ssl:443 ssl crt /etc/haproxy/site.pem
    bind unix@ssl-frontend.sock user root mode 600 accept-proxy

listen external_bind_app1             #监听file descriptor
    bind "fd@${FD_APP1}"

 生产示例:

frontend wang_web_port                 #建议采用后面形式命名:业务-服务-端口号
    bind :80,:8080
    bind 10.0.0.7:10080,:8801-8810,10.0.0.17:9001-9010
    mode 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_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

就是把主配置文件的东西移到指定配置文件 ,也可以根据业务写,一个业务一个

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 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 算法  根据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
random

leastconn         #数据库
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 -t

nginx -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 Settings

 access_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 5

backend 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.org

openssl req  -x509 -newkey rsa:2048 -subj $CA_SUBJECT -keyout ca.key -nodes -days 202002 -out ca.crt

openssl req -newkey rsa:2048 -nodes -keyout ${FILE}.key  -subj $SUBJECT -out ${FILE}.csr

openssl x509 -req -in ${FILE}.csr  -CA ca.crt -CAkey ca.key -set_serial $SERIAL  -days $EXPIRE -out ${FILE}.crt

chmod 600 ${FILE}.key ca.key

 指定公网地址,用ssl加密 证书文件

redirect scheme https if !{ ssl_fc }    #这行的意思大概就是把不是s的装换成s 

 

 满足条件跳转https,不满足跳别的

 

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值