HAProxy负载均衡

HAProxy

HAProxy简介

👉haproxy官网 👉haproxy官方帮助文档

HAProxy是一个免费的负载均衡软件,可以运行于大部分主流的Linux操作系统上。

HAProxy提供了L4(TCP)和L7(HTTP)两种负载均衡能力,具备丰富的功能。HAProxy的社区非常活跃,版本更新快速(最新稳定版1.7.2于2017/01/13推出)。最关键的是,HAProxy具备媲美商用负载均衡器的性能和稳定性。

因为HAProxy的上述优点,它当前不仅仅是免费负载均衡软件的首选,更几乎成为了唯一选择。

HAProxy的核心能力与关键特性

HAProxy的核心功能

  • 负载均衡:L4和L7两种模式,支持RR/静态RR/LC/IP Hash/URI Hash/URL_PARAM Hash/HTTP_HEADER Hash等丰富的负载均衡算法
  • 健康检查:支持TCP和HTTP两种健康检查模式
  • 会话保持:对于未实现会话共享的应用集群,可通过Insert Cookie/Rewrite Cookie/Prefix Cookie,以及上述的多种Hash方式实现会话保持
  • SSL:HAProxy可以解析HTTPS协议,并能够将请求解密为HTTP后向后端传输
  • HTTP请求重写与重定向
  • 监控与统计:HAProxy提供了基于Web的统计信息页面,展现健康状态和流量数据。基于此功能,使用者可以开发监控程序来监控HAProxy的状态

HAProxy的关键特性

性能

  • 采用单线程、事件驱动、非阻塞模型,减少上下文切换的消耗,能在1ms内处理数百个请求。并且每个会话只占用数KB的内存。
  • 大量精细的性能优化,如O(1)复杂度的事件检查器、延迟更新技术、Single-buffereing、Zero-copy forwarding等等,这些技术使得HAProxy在中等负载下只占用极低的CPU资源。
  • HAProxy大量利用操作系统本身的功能特性,使得其在处理请求时能发挥极高的性能,通常情况下,HAProxy自身只占用15%的处理时间,剩余的85%都是在系统内核层完成的。
  • HAProxy作者在8年前(2009)年使用1.4版本进行了一次测试,单个HAProxy进程的处理能力突破了10万请求/秒,并轻松占满了10Gbps的网络带宽。

稳定性

作为建议以单进程模式运行的程序,HAProxy对稳定性的要求是十分严苛的。按照作者的说法,HAProxy在13年间从未出现过一个会导致其崩溃的BUG,HAProxy一旦成功启动,除非操作系统或硬件故障,否则就不会崩溃(我觉得可能多少还是有夸大的成分)。

在上文中提到过,HAProxy的大部分工作都是在操作系统内核完成的,所以HAProxy的稳定性主要依赖于操作系统,作者建议使用2.6或3.x的Linux内核,对sysctls参数进行精细的优化,并且确保主机有足够的内存。这样HAProxy就能够持续满负载稳定运行数年之久。


HAProxy关键配置详解

总览

HAProxy的配置文件共有5个域

  • global:用于配置全局参数
  • default:用于配置所有frontend和backend的默认属性
  • frontend:用于配置前端服务(即HAProxy自身提供的服务)实例
  • backend:用于配置后端服务(即HAProxy后面接的服务)实例组
  • listen:frontend+backend的组合配置,可以理解成更简洁的配置方法
global(全局)域的关键配置
daemon:指定HAProxy以后台模式运行,通常情况下都应该使用这一配置
user [username] :指定HAProxy进程所属的用户
group [groupname] :指定HAProxy进程所属的用户组
log [address] [device] [maxlevel] [minlevel]:日志输出配置,如log 127.0.0.1 local0 info warning,即向本机rsyslog或syslog的local0输出info到warning级别的日志。其中[minlevel]可以省略。HAProxy的日志共有8个级别,从高到低为emerg/alert/crit/err/warning/notice/info/debug
pidfile :指定记录HAProxy进程号的文件绝对路径。主要用于HAProxy进程的停止和重启动作。
maxconn :HAProxy进程同时处理的连接数,当连接数达到这一数值时,HAProxy将停止接收连接请求
frontend(前端)域的关键配置
acl [name] [criterion] [flags] [operator] [value]:定义一条ACL,ACL是根据数据包的指定属性以指定表达式计算出的true/false值。如"acl url_ms1 path_beg -i /ms1/"定义了名为url_ms1的ACL,该ACL在请求uri以/ms1/开头(忽略大小写)时为true
bind [ip]:[port]:frontend服务监听的端口
default_backend [name]:frontend对应的默认backend
disabled:禁用此frontend
http-request [operation] [condition]:对所有到达此frontend的HTTP请求应用的策略,例如可以拒绝、要求认证、添加header、替换header、定义ACL等等。
http-response [operation] [condition]:对所有从此frontend返回的HTTP响应应用的策略,大体同上
log:同global域的log配置,仅应用于此frontend。如果要沿用global域的log配置,则此处配置为log global
maxconn:同global域的maxconn,仅应用于此frontend
mode:此frontend的工作模式,主要有http和tcp两种,对应L7和L4两种负载均衡模式
option forwardfor:在请求中添加X-Forwarded-For Header,记录客户端ip
option http-keep-alive:以KeepAlive模式提供服务
option httpclose:与http-keep-alive对应,关闭KeepAlive模式,如果HAProxy主要提供的是接口类型的服务,可以考虑采用httpclose模式,以节省连接数资源。但如果这样做了,接口的调用端将不能使用HTTP连接池
option httplog:开启httplog,HAProxy将会以类似Apache HTTP或Nginx的格式来记录请求日志
option tcplog:开启tcplog,HAProxy将会在日志中记录数据包在传输层的更多属性
stats uri [uri]:在此frontend上开启监控页面,通过[uri]访问
stats refresh [time]:监控数据刷新周期
stats auth [user]:[password]:监控页面的认证用户名密码
timeout client [time]:指连接创建后,客户端持续不发送数据的超时时间
timeout http-request [time]:指连接创建后,客户端没能发送完整HTTP请求的超时时间,主要用于防止DoS类攻击,即创建连接后,以非常缓慢的速度发送请求包,导致HAProxy连接被长时间占用
use_backend [backend] if|unless [acl]:与ACL搭配使用,在满足/不满足ACL时转发至指定的backend
backend(后端)域的关键配置
acl:同frontend域
balance [algorithm]:在此backend下所有server间的负载均衡算法,常用的有roundrobin和source,完整的算法说明见官方文档configuration.html#4.2-balance
cookie:在backend server间启用基于cookie的会话保持策略,最常用的是insert方式,如cookie HA_STICKY_ms1 insert indirect nocache,指HAProxy将在响应中插入名为HA_STICKY_ms1的cookie,其值为对应的server定义中指定的值,并根据请求中此cookie的值决定转发至哪个server。indirect代表如果请求中已经带有合法的HA_STICK_ms1 cookie,则HAProxy不会在响应中再次插入此cookie,nocache则代表禁止链路上的所有网关和缓存服务器缓存带有Set-Cookie头的响应。
default-server:用于指定此backend下所有server的默认设置。具体见下面的server配置。
disabled:禁用此backend
http-request/http-response:同frontend域
log:同frontend域
mode:同frontend域
option forwardfor:同frontend域
option http-keep-alive:同frontend域
option httpclose:同frontend域
option httpchk [METHOD] [URL] [VERSION]:定义以http方式进行的健康检查策略。如option httpchk GET /healthCheck.html HTTP/1.1
option httplog:同frontend域
option tcplog:同frontend域
server [name] [ip]:[port] [params]:定义backend中的一个后端server,[params]用于指定这个server的参数,常用的包括有:
	check:指定此参数时,HAProxy将会对此server执行健康检查,检查方法在option httpchk中配置。同时还可以在check后指定		inter, rise, fall三个参数,分别代表健康检查的周期、连续几次成功认为server UP,连续几次失败认为server DOWN,默认值	   是inter 2000ms rise 2 fall 3
	cookie [value]:用于配合基于cookie的会话保持,如cookie ms1.srv1代表交由此server处理的请求会在响应中写入值为		ms1.srv1的cookie(具体的cookie名则在backend域中的cookie设置中指定)
	maxconn:指HAProxy最多同时向此server发起的连接数,当连接数到达maxconn后,向此server发起的新连接会进入等待队列。默	 认为0,即无限
	maxqueue:等待队列的长度,当队列已满后,后续请求将会发至此backend下的其他server,默认为0,即无限
	weight:server的权重,0-256,权重越大,分给这个server的请求就越多。weight为0的server将不会被分配任何新的连接。所	  有server默认weight为1
timeout connect [time]:指HAProxy尝试与backend server创建连接的超时时间
timeout check [time]:默认情况下,健康检查的连接+响应超时时间为server命令中指定的inter值,如果配置了timeout check,HAProxy会以inter作为健康检查请求的连接超时时间,并以timeout check的值作为健康检查请求的响应超时时间
timeout server [time]:指backend server响应HAProxy请求的超时时间

default域

上文所属的frontend和backend域关键配置中,除acl、bind、http-request、http-response、use_backend外,其余的均可以配置在default域中。default域中配置了的项目,如果在frontend或backend域中没有配置,将会使用default域中的配置。

listen域

listen域是frontend域和backend域的组合,frontend域和backend域中所有的配置都可以配置在listen域下


HAProxy搭建http负载均衡

环境说明

主机名IP地址部署的应用操作系统
LB192.168.92.130haproxyCentos8
web01192.168.92.132httpdCentos8
web02192.168.92.131httpdCentos8
client192.168.92.149Centos8

LB主机为负载均衡服务器。web01与web02为RS(真实服务器,也可叫做应用服务器)。client主机是用于充当客户端主机测试访问负载均衡需求是否实现的。

注意:LB、web01、web02都需关闭防火墙与SELinux

部署RS的httpd

web01配置

[root@web01 ~]# dnf -y install httpd
[root@web01 ~]# echo 'RS1' > /var/www/html/index.html
[root@web01 ~]# systemctl enable --now httpd
[root@web01 ~]# ss -anlt
State     Recv-Q    Send-Q       Local Address:Port        Peer Address:Port    Process
LISTEN    0         128                0.0.0.0:22               0.0.0.0:*
LISTEN    0         128                      *:80                     *:*
LISTEN    0         128                   [::]:22                  [::]:*

web02配置

[root@web02 ~]# dnf -y install httpd
[root@web02 ~]# echo 'RS2' > /var/www/html/index.html
[root@web02 ~]# systemctl enable --now httpd
[root@web02 ~]# ss -anlt
State     Recv-Q    Send-Q       Local Address:Port        Peer Address:Port    Process
LISTEN    0         128                0.0.0.0:22               0.0.0.0:*
LISTEN    0         128                      *:80                     *:*
LISTEN    0         128                   [::]:22                  [::]:*

部署harproxy

#下载源码编译依赖包
[root@LB ~]# dnf -y install make gcc pcre-devel bzip2-devel openssl-devel systemd-devel

#创建haproxy用户
[root@LB ~]# useradd -Mrs /sbin/nologin haproxy
[root@LB ~]# id haproxy
uid=995(haproxy) gid=992(haproxy) groups=992(haproxy)

#下载并解压haproxy源码包
[root@LB ~]# cd /usr/local/src/
[root@LB src]# wget https://www.haproxy.org/download/2.6/src/haproxy-2.6.6.tar.gz
[root@LB src]# tar -xf haproxy-2.6.6.tar.gz

#编译安装haproxy
[root@LB src]# cd haproxy-2.6.6/
[root@LB haproxy-2.6.6]# make clean
[root@LB haproxy-2.6.6]# make -j $(grep 'processor' /proc/cpuinfo | wc -l) \
TARGET=linux-glibc \
USE_OPENSSL=1 \
USE_ZLIB=1 \
USE_PCRE=1 \
USE_SYSTEMD=1
[root@LB haproxy-2.6.6]# make install PREFIX=/usr/local/haproxy
[root@LB haproxy-2.6.6]# cp haproxy /usr/sbin/

#设置Linux内核参数
[root@LB ~]# echo 'net.ipv4.ip_nonlocal_bind = 1' >> /etc/sysctl.conf
[root@LB ~]# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
[root@LB ~]# sysctl -p
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1

#配置haproxy服务
[root@LB ~]# mkdir /etc/haproxy
[root@LB ~]# cat > /etc/haproxy/haproxy.cfg <<EOF
#--------------全局配置----------------
global
    log 127.0.0.1 local0  info	#定义haproxy日志输出设置
    #log loghost local0 info
    maxconn 20480	#最大连接数
#chroot /usr/local/haproxy	#chroot运行路径
    pidfile /var/run/haproxy.pid	#haproxy进程pid文件
    #maxconn 4000
    user haproxy	#运行haproxy用户,可用uid代替
    group haproxy   #运行haproxy用户组,可用gid代替
    daemon			#以守护进程(后台进程)运行haproxy
#---------------------------------------------------------------------
#common defaults that all the 'listen' and 'backend' sections will
#use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode http		#所处理的类别(7层代理http,4层代理tcp)
    log global		#引入global定义的日志格式
    option dontlognull	#不记录监控检查日志信息
    option httpclose	#每次请求完毕后主动关闭http通道,haproxy不支持keep-alive(保持运行)模式
    option httplog		#日志类别为http日志格式
    #option forwardfor	#如果后端服务器需要获取客户端的真实ip,需要配置的参数,可以从http header中获取客户端的ip
    option redispatch
    balance roundrobin		#设置默认负载均衡方式为轮询
    timeout connect 10s		#默认连接超时时间
    timeout client 10s		#默认客户端超时时间
    timeout server 10s		#默认服务端超时时间
    timeout check 10s		#设置超时检查超时时间
    maxconn 60000			#最大连接数
    retries 3		#3次连接失败就认为服务器不可用
#--------------统计页面配置------------------
listen admin_stats
    bind 0.0.0.0:8189	#监听端口
    stats enable		#开启监控
    mode http
    log global
    stats uri /haproxy_stats	#监控页面的url访问路径
    stats realm Haproxy\ Statistics	#监控页面的提示信息
    stats auth admin:admin		#监控页面的用户和密码
    #stats hide-version			#隐藏统计页面上的haproxy版本信息
    stats admin if TRUE			#手动启用/禁用,后端服务器haproxy
    stats refresh 30s			#每30秒自动刷新监控页面
#---------------web设置-----------------------
listen webcluster
    bind 0.0.0.0:80
    mode http
    #option httpchk GET /index.html
    log global
    maxconn 3000
    balance roundrobin		#设置均衡负载方式为轮询
    cookie SESSION_COOKIE insert indirect nocache
    server web01 192.168.92.132:80 check inter 2000 fall 5	#配置web01主机的IP+端口
    server web02 192.168.92.131:80 check inter 2000 fall 5	 #配置web02主机的IP+端口
EOF

#配置haproxy.service服务单元文件
[root@LB ~]# cat > /usr/lib/systemd/system/haproxy.service <<EOF
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target

[Service]
ExecStartPre=/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg   -c -q
ExecStart=/usr/local/haproxy/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg  -p /var/run/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target
EOF

[root@LB ~]# systemctl daemon-reload

#启用日志
[root@LB ~]# vim /etc/rsyslog.conf
local0.*        /var/log/haproxy.log
[root@LB ~]# systemctl restart rsyslog.service

#启动服务
[root@LB ~]# systemctl enable --now haproxy.service
#看到8189端口与80端口起来了就说明成功了
[root@LB ~]# ss -anlt
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port     
LISTEN 0      128          0.0.0.0:22         0.0.0.0:*                                                                    
LISTEN 0      128          0.0.0.0:8189       0.0.0.0:*                                                                    
LISTEN 0      128          0.0.0.0:80         0.0.0.0:*                                                                    
LISTEN 0      128             [::]:22            [::]:*

client端进行测试

[root@client ~]# curl 192.168.92.130
RS1
[root@client ~]# curl 192.168.92.130
RS2
[root@client ~]# curl 192.168.92.130
RS1
[root@client ~]# curl 192.168.92.130
RS2

web监控页面

使用ip+8189端口+配置文件自行定义的url访问路径。用户名与密码也是配置文件自行定义的。忘了的话去查看haproxy的配置文件!

image-20220927234259238

image-20220927234306784

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值