文章目录
- 一、Haproxy 相关概念
- 1. Haproxy 的概述
- 2. Haproxy 的主要特性
- 3. 常见的 Web 集群调度器
- 4. 常见的应用分析
- 4.1 LVS 应用
- 4.2 Haproxy 应用
- 4.3 LVS、Nginx、Haproxy的区别
- 5. Haproxy 调度算法原理
- 5.1 roundrobin
- 5.2 static-rr
- 5.3 leastconn
- 5.4 source
- 5.5 uri
- 5.6 url_param
- 5.7 hdr(name)
- 5.8 rdp-cookie(name)
- 二、Haproxy 群集配置
- 1. 准备工作
- 2. haproxy 服务器部署(一)
- 2.1 关闭防火墙,将安装Haproxy所需软件包传到/opt目录下
- 2.2 安装 Haproxy
- 2.3 Haproxy服务器配置
- 2.4 节点服务器部署(两个服务器)
- 2.5 客户端访问测试
- 3. haproxy 服务器部署(二)
- 3.1 节点服务器配置
- 3.2 客户端访问测试
- 4. 定义监控页面
- 5. 日志定义
- 5.1 方法一
- 5.2 方法二
- 三、用Keepalived+Haproxy实现高可用负载均衡
- 1. Keepalived 安装配置
- 1.1 安装
- 1.2 高可用配置
- 1.3 启动
- 2. HAProxy 安装配置
- 2.1 安装
- 2.2 基本配置
- 2.3 启动
- 2.4会话保持
- 四、内核优化
- 五、总结
- 1. LVS、Nginx、Haproxy 的区别
- 2. Haproxy 调度算法原理(8种)
一、Haproxy 相关概念
1. Haproxy 的概述
Haproxy是可提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,是免费、快速并且可靠的一种解决方案。Haproxy非常适用于并发大(并发达1w以上)web站点,这些站点通常又需要会话保持或七层处理。Haproxy的运行模式使得它可以很简单安全的整合至当前的架构中,同时可以保护web服务器不被暴露到网络上。
2. Haproxy 的主要特性
- 可靠性和稳定性非常好,可以与硬件级的F5负载均衡设备相媲美;
- 最高可以同时维护40000-50000个并发连接,单位时间内处理的最大请求数为20000个,最大处理能力可达10Git/s;
- 支持多达8种负载均衡算法;
- 支持Session会话保持,Cookie的引导;
- 支持通过获取指定的ur1来检后端服务器的状态;
- 支持虚机主机功能,从而实现web负载均衡更加灵活;
- 支持连接拒绝、全透明代理等独特的功能;
- 拥有强大的ACL支持,用于访问控制制;
- 支持TCP协议的负载均衡转发;
- 支持客户端的keepalive功能,减少客户端与haproxy的多次三次握手导致资源浪费,让多个请求在一个tcp连接中完成。
3. 常见的 Web 集群调度器
目前常见的Web集群调度器分为软件和硬件。
软件通常使用开源的LVS、Haproxy、Nginx。其中LVS 性能最好,但是搭建相对复杂;而Nginx 的 upstream模块支持群集功能,但是对群集节点健康检查功能不强,高并发性能没有 Haproxy好。
硬件一般使用比较多的是F5、Array,也有很多人使用国内的一些产品,如梭子鱼、绿盟等。
4. 常见的应用分析
4.1 LVS 应用
- LVS在企业应用中抗负载能力很强,但存在不足。
- LVS不支持正则处理,不能实现动静分离。
- 对于大型网站,LVS的实施配置复杂,维护成本相对较高。
4.2 Haproxy 应用
- Haproxy是一款可提供高可用性、负载均衡、及基于TCP和HTTP应用的代理软件。
- 适用于负载大的web站点。
- 运行在硬件上可支持数以万计的并发连接的连接请求。
4.3 LVS、Nginx、Haproxy的区别
软件的负载均衡性能
Haproxy功能强大,单纯从效率上来讲Haproxy会比Nginx有更出色的负载均衡速度。在并发处理上也是优于Nginx的。但整体性能低于4层模式的LVS负载均衡。
支持的代理类型
LVS基于Linux操作系统内核实现软负载均衡,只能支持4层代理的IP转发(不支持正则表达式)。
而Haproxy和Nginx是基于第三方应用(应用程序)实现的软负载均衡,都支持4层和7层转发(支持正则表达式)。
支持的健康检查方式
LVS因为工作在ISO模型的第四层,其状态监测功能单一,支持对端口和URL进行检查。
而Haproxy在状态监测方面功能更丰富、强大,可支持端口、URL、脚本等多种状态检测方式。
Nginx主要用于web服务器或缓存服务器。Nginx的upstream模块虽然也支持群集功能,但是性能没有LVS和Haproxy好,对群集节点健康检查功能不强,只支持通过端口来检测,不支持通过URL来检测。
5. Haproxy 调度算法原理
Haproxy 支持多种调度算法,最常用的有八种,分别是roundrobin、static-rr、leastconn、source、uri、url_param、hdr(name)、rdp-cookie(name)。
调度算法 | 中文含义 |
---|---|
roundrobin | 轮询 |
static-rr | 加权轮询 |
leastconn | 最小连接数 |
source | 根据源地址哈希 |
uri | 根据URL哈希 |
url_param | 根据URL参数哈希 |
hdr(name) | 根据请求头哈希 |
rdp-cookie(name) | 根据cookie哈希 |
5.1 roundrobin
roundrobin算法是最简单最常用的一种算法,即轮询调度。
5.2 static-rr
静态轮询,基于权重轮询调度,不支持Haproxy在运行时进行权重调整和后端服务器的慢启动,后端的主机数量没有限制。
5.3 leastconn
LC(Least Connections)最小连接数算法,根据后端的节点连接数大小动态分配前端请求。
5.4 source
基于来源访问调度算法,用于一些有Session会记录在服务器端的场景,可以基于来源的IP、Cookie等做集群调度。
5.5 uri
目的地址哈希,表示根据用户请求的URI做hash,做cdn时需要使用。(cdn:内容分发网络 ,边缘网络缓存加速)。url_hash 就是根据虚拟主机名称后面的目录。
5.6 url_param
表示根据请求的URl参数’balance url_ param’ requires an URL parameter name。
5.7 hdr(name)
表示根据HTTP请求头来锁定每一次HTTP请求。
5.8 rdp-cookie(name)
表示根据cookie (name)来锁定并哈希每一次TCP请求。
二、Haproxy 群集配置
1. 准备工作
Haproxy服务器:192.168.145.15
Nginx 服务器1:192.168.145.30
Nginx 服务器2:192.168.145.45
客户端:12.0.0.10
2. haproxy 服务器部署(一)
2.1 关闭防火墙,将安装Haproxy所需软件包传到/opt目录下
[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# setenforce 0
2.2 安装 Haproxy
yum安装方式
[root@localhost ~]# yum install -y haproxy
2.3 Haproxy服务器配置
[root@localhost ~]# vim /etc/haproxy/haproxy.cfg
HAProxy 的配置文件共有 5 个域:
global
:用于配置全局参数default
:用于配置所有frontend和backend的默认属性frontend
:用于配置前端服务(即HAProxy自身提供的服务)实例backend
:用于配置后端服务(即HAProxy后面接的服务)实例组listen
:frontend
+backend
的组合配置,可以理解成更简洁的配置方法,frontend
域和backend
域中所有的配置都可以配置在listen域下
#全局配置,主要用于定义全局参数,属于进程级的配置,通常和操作系统配置有关
global
log 127.0.0.1 local0 info #将info(及以上)的日志发送到rsyslog的local0接口
log 127.0.0.1 local1 warning #将warning(及以上)的日志发送到rsyslog的local1接口
#chroot /var/lib/haproxy #修改haproxy工作目录至指定目录,一般需将此行注释掉
pidfile /var/run/haproxy.pid #指定保存HAProxy进程号的文件
maxconn 40000 #最大连接数,HAProxy 要求系统的 ulimit -n 参数大于 maxconn*2+18
user haproxy #以指定的用户名身份运行haproxy进程
group haproxy #以指定的组名运行haproxy,以免因权限问题带来风险
daemon #让haproxy以守护进程的方式工作于后台
spread-checks 2 #在haproxy后端有着众多服务器的场景中,在精确的时间间隔后统一对众服务器进行健康状况检查可能会带来意外问题;此选项用于将其检查的时间间隔长度上增加或减小一定的随机时长;默认为0,官方建议设置为2到5之间。
#nbproc 2 #指定启动的haproxy进程个数,只能用于守护进程模式的haproxy,默认只启动一个进程。
#配置默认参数,这些参数可以被用到listen,frontend,backend组件
defaults
mode http #模式为http(7层代理http,4层代理tcp)
log global #所有前端都默认使用global中的日志配置
option httplog #开启httplog,在日志中记录http请求、session信息等。http模式时开启httplog,tcp模式时开启tcplog
option dontlognull #不在日志中记录空连接
option http-keep-alive #使用keepAlive连接,后端为静态建议使用http-keep-alive,后端为动态应用程序建议使用http-server-close
option forwardfor except 127.0.0.0/8 #记录客户端IP在X-Forwarded-For头域中,haproxy将在发往后端的请求中加上"X-Forwarded-For"首部字段
option redispatch #当某后端down掉使得haproxy无法转发携带cookie的请求到该后端时,将其转发到别的后端上
retries 3 #定义连接后端服务器的失败重连次数,连接失败次数超过此值后会将对应后端服务器标记为不可用
timeout http-request 10s #默认http请求超时时间,此为等待客户端发送完整请求的最大时长,用于避免类DoS攻击。haproxy总是要求一次请求或响应全部发送完成后才会处理、转发
timeout queue 1m #默认客户端请求在队列中的最大时长
timeout connect 10s #默认haproxy和服务端建立连接的最大时长,新版本中替代contimeout,该参数向后兼容
timeout client 1m #默认和客户端保持空闲连接的超时时长,在高并发下可稍微短一点,可设置为10秒以尽快释放连接,新版本中替代clitimeout
timeout server 1m #默认和服务端保持空闲连接的超时时长,局域网内建立连接很快,所以尽量设置短一些,特别是高并发时,新版本中替代srvtimeout
timeout http-keep-alive 10s #默认和客户端保持长连接的最大时长。优先级高于timeout http-request 也高于timeout client
timeout check 10s #和后端服务器成功建立连接后到最终完成检查的最大时长(不包括建立连接的时间,只是读取到检查结果的时长)
maxconn 30000 #最大连接数,“defaults”中的值不能超过“global”段中的定义
老版本的haproxy中是以下几项:
contimeout 5000
:设置连接超时时间,默认单位是毫秒。clitimeout 50000
:设置客户端超时时间,默认单位是毫秒。srvtimeout 50000
:设置服务器超时时间,默认单位是毫秒。
frontend http-in
###监听任意地址的80端口号
bind *:80
###通过acl过滤符合条件的静态页面请求
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
###将符合acl条件的静态页面情景求转发到static——backend后端域,将其他所有请求转发到dynamic_backend后端与中
use_backend static_backend if url_static
default_backend dynamic_backend
#定义后端域static_backend
backend static_backend
balance roundrobin #使用轮询算法
option httpchk GET /test.html #表示基于http协议来做健康状况检查,只有返回状态码为2xx或3xx的才认为是健康的,其余所有状态码都认为不健康。不设置该选项时,默认采用tcp做健康检查,只要能建立tcp就表示健康。
server inst1 192.168.145.30:80 check inter 2000 rise 2 fall 3
server inst2 192.168.145.45:80 check inter 2000 rise 2 fall 3
#同上,inter 2000 rise 2 fall 3是默认值,可以省略
#定义后端域dynamic_backend
backend dynamic_backend
balance roundrobin
option http-server-close
cookie HA_STICKY_dy insert indirect nocache
server app1 192.168.145.30:8080 cookie appser1 check
server app2 192.168.145.45:8080 cookie appser2 check
2.4 节点服务器部署(两个服务器)
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
setenforce: SELinux is disabled
[root@localhost ~]# yum install -y httpd
[root@localhost ~]# cd /var/www/html
[root@localhost html]# mkdir static
[root@localhost html]# echo '<h1>this is first</h1>' > /static/index.html
[root@localhost html]# systemctl start httpd
2.5 客户端访问测试
http://192.168.145.15/statci/index.html
3. haproxy 服务器部署(二)
3.1 节点服务器配置
[root@localhost html]# cd /opt/
[root@localhost opt]# ls
rh
[root@localhost opt]# rz -E
rz waiting to receive.
[root@localhost opt]# tar xf apache-tomcat-9.0.16.tar.gz
[root@localhost opt]# java -version
openjdk version "1.8.0_262"
OpenJDK Runtime Environment (build 1.8.0_262-b10)
OpenJDK 64-Bit Server VM (build 25.262-b10, mixed mode)
[root@localhost opt]# mv apache-tomcat-9.0.16 /usr/local/tomcat
[root@localhost opt]# cd /usr/local/tomcat/
[root@localhost tomcat]# ls
bin conf lib logs README.md RUNNING.txt webapps
BUILDING.txt CONTRIBUTING.md LICENSE NOTICE RELEASE-NOTES temp work
[root@localhost tomcat]# cd bin/
[root@localhost bin]# ./startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@localhost bin]# netstat -lntp | grep :8080
tcp6 0 0 :::8080 :::* LISTEN 67731/java
[root@localhost bin]# cd ..
[root@localhost tomcat]# cd webapps/
[root@localhost webapps]# mkdir test
[root@localhost webapps]# echo '<h1>this is tomcat1 jsp page</h1>' > test/index.jsp
haproxy服务器需要将 cookie HA_STICKY_dy insert indirect nocache
选项注释掉
3.2 客户端访问测试
http://192.168.145.15/test/index.jsp
4. 定义监控页面
[root@localhost ~]# vim /etc/haproxy/haproxy.cfg
listen stats
bind *:1080 #绑定端口1080
stats enable #启用统计报告监控
stats refresh 30s #每30秒更新监控数据
stats uri /stats #访问监控页面的uri
stats realm HAProxy\ Stats #监控页面的认证提示
stats auth admin:admin #监控页面的用户名和密码
[root@localhost haproxy]# systemctl restart haproxy.service
[root@localhost haproxy]# systemctl status haproxy.service
● haproxy.service - HAProxy Load Balancer
Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)
Active: active (running) since 一 2023-06-12 16:56:16 CST; 11s ago
Main PID: 68625 (haproxy-systemd)
Tasks: 3
CGroup: /system.slice/haproxy.service
├─68625 /usr/sbin/haproxy-systemd-wrapper -f /etc/haproxy/haproxy.cfg -p /run...
├─68626 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds...
└─68627 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds...
6月 12 16:56:16 localhost.localdomain systemd[1]: Started HAProxy Load Balancer.
6月 12 16:56:16 localhost.localdomain haproxy-systemd-wrapper[68625]: haproxy-systemd-w...
浏览器访问 http://192.168.145.15:1080/stats
5. 日志定义
默认 haproxy 的日志是输出到系统的 syslog 中,查看起来不是非常方便,为了更好的管理 haproxy 的日志,我们在生产环境中一般单独定义出来。需要将 haproxy 的 info 及 notice 日志分别记录到不同的日志文件中。
5.1 方法一
#修改haproxy.cfg,将info及以上级别的日志发送到rsyslog的local0接口,将warning及以上级别的日志发送到rsyslog的local1接口
[root@localhost ~]# vim /etc/haproxy/haproxy.cfg
global
......
log 127.0.0.1 local0 info
log 127.0.0.1 local1 warning
......
defaults
......
log global
......
注:信息级日志会打印HAProxy 的每一条请求处理,会占用大量的磁盘空间,在生产环境中,将日志级别调整为notice
[root@localhost ~]# mkdir /var/log/haproxy
[root@localhost ~]# vim /etc/rsyslog.d/haproxy.conf
$ModLoad imudp
$UDPServerRun 514
$FileCreateMode 0644 #日志文件的权限
$FileOwner haproxy #日志文件的owner
local0.* /var/log/haproxy/haproxy_info.log #local0接口对应的日志输出文件
local1.* /var/log/haproxy/haproxy_warning.log #local1接口对应的日志输出文件
#修改 rsyslog 的启动参数
[root@localhost ~]# vim /etc/sysconfig/rsyslog
SYSLOGD_OPTIONS="-c 2 -r -m 0"
#重启 rsyslog 和 HAProxy
[root@localhost ~]# systemctl restart haproxy.service
[root@localhost ~]# systemctl restart rsyslog.service
[root@localhost ~]# cd /var/log/haproxy/
[root@localhost haproxy]# ls
haproxy_info.log
5.2 方法二
[root@localhost ~]# vim /etc/haproxy/haproxy.cfg
global
log /dev/log local0 info
log /dev/log local0 notice
......
defaults
......
log global
......
#需要修改rsyslog配置,为了便于管理。将haproxy相关的配置独立定义到haproxy.conf,并放到/etc/rsyslog.d/下,rsyslog启动时会自动加载此目录下的所有配置文件。
[root@localhost ~]# vim /etc/rsyslog.d/haproxy.conf
if ($programname == 'haproxy' and $syslogseverity-text == 'info')
then -/var/log/haproxy/haproxy-info.log
&~
if ($programname == 'haproxy' and $syslogseverity-text == 'notice')
then -/var/log/haproxy/haproxy-notice.log
&~
#说明:
这部分配置是将haproxy的info日志记录到/var/log/haproxy/haproxy-info.log下,将notice日志记录到/var/log/haproxy/haproxy-notice.log下。“&~”表示当日志写入到日志文件后,rsyslog停止处理这个信息。
[root@localhost ~]# service rsyslog restart
[root@localhost ~]# service haproxy restart
[root@localhost ~]# tail -f /var/log/haproxy/haproxy-info.log #查看haproxy的访问请求日志信息
三、用Keepalived+Haproxy实现高可用负载均衡
1. Keepalived 安装配置
1.1 安装
Keepalived支持源码安装,同时也可以通过不同操作系统安装工具进行安装,本文以CentOS的yum工具为例进行安装介绍。此时应该准备两台服务器分别作为Master节点和Backup节点,分别在两台服务器上执行以下命令进行安装。
yum install -y keepalived
1.2 高可用配置
yum安装后,Keepalived将生成配置文件:/etc/keepalived/keepalived.conf,可利用文本编辑器进行配置修改。
vim /etc/keepalived/keepalived.conf
配置文件中主要由全局段、VRRP实例段、脚本段组成。
全局段定义(global_defs)
全局段定义允许用户设置全局相关信息,例如通知信息、关键参数配置等,该段配置在Master节点和Backup节点上应当一致。
global_defs {
notification_email {
sysadmin@example.com
}
notification_email_from noreply@example.com
smtp_server 127.0.0.1
smtp_connect_timeout 60
vrrp_mcast_group4 224.0.0.18
}
notification_email定义报警邮件地址,当服务切换时发送报警邮件。notification_email_from定义发件人信息,smtp_server和smtp_connect_timeout分别定义了SMTP服务器及相应的连接超时时间,vrrp_mcast_group4为VRRP IPv4多播地址,默认为224.0.0.18,如果同一局域网内有多组Keepalived时需要指定不同多播地址。
VRRP实例段定义(vrrp_instance)
这部分主要用来定义具体服务的实例配置,包括Keepalived主备状态、接口、优先级、认证方式和VIP信息等,每个VRRP实例可以认为是Keepalived服务的一个实例或作为一个业务服务,在一组Keepalived服务配置中,VRRP实例可以有多个。
注意,存在于Master节点中的VRRP实例配置在Backup节点中也要有一致的配置(除了节点角色、优先级不同),这样才能实现故障切换转移。
vrrp_instance R1{
state MASTER
interface eth0
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass passwd
}
virtual_ipaddress {
10.230.137.100
}
track_script {
chk_haproxy
}
nopreempt
preempt_delay 2
}
vrrp_instance配置段定义了一个VRRP实例并设定实例名称;
state设定初始VRRP实例角色,配置先要为该实例所在的Keepalived服务器设定其角色,在Master服务器上设置为“MASTER”,在Backup服务器上则设置为“BACKUP”;
priority优先级设定,范围1-254,数字越大,表示实例优先级越高,在同一个VRRP实例里,Master节点优先级要高于Backup节点;
virtual_router_id虚拟路由ID标识,范围0-255,Master和Backup节点配置中相同VRRP实例的虚拟路由ID标识必须一致,否则将出现脑裂问题;
advert_int用来同步通知间隔,Master节点和Backup节点之间通信检查的时间间隔,单位是秒。
角色相关信息设定完毕后就要开始配置VIP并绑定至指定的网络接口上,在virtual_ipaddress中配置VIP,可以配置多个VIP,VIP将绑定至interface参数配置的网络接口上。
authentication认证配置段作用于同一个VRRP实例的MASTER和BACKUP之前的通信,具体的配置内容有auth_type认证类型,auth_pass认证密码,认证类型有PASS(Simple Passwd)和AH(IPSEC),官方推荐PASS,验证密码为明文方式,最多8位。同一个VRRP实例的MASTER和BACKUP使用相同的密码才能正常通信。
当添加nopreemp关键字时表示设置高可用模式为非抢占模式,如果去掉此关键字则为默认的抢占模式。抢占模式是指当高优先级节点恢复后会抢占低优先级节点成为MASTER,非抢占模式允许低优先级节点继续担任MASTER,preempt_delay用来设置抢占延迟,单位秒,范围0~1000,发现低优先级MASTER后多少秒开始抢占。
脚本段定义(vrrp_script)
默认情况下,Keepalived仅仅在节点宕机或Keepalived进程停掉的时候才会启动切换机制。但在实际工作中,有业务服务停止而Keepalived服务还存在的情况,这就会导致用户访问的VIP无法找到对应的服务,这时可以利用Keepalived触发预制的监测脚本,实现VIP漂移来继续提供服务。
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 2
weight -2
fall 3
rise 1
}
vrrp_script配置段定义一段脚本配置并设定脚本段名称。script用双引号设置引用的shell语句或者shell脚本,通过该语句或脚本执行结果来判断是否触发指定动作,成功的结果不会触发动作,执行失败会触发动作。interval设置监控间隔时间,单位为秒,weight设置当监控脚本执行结果为失败时触发priority值调整,正数为增加优先级,负数为降低优先级,范围-255~255,fall设置认定结果为失败时的执行失败次数,rise设置判定结果为成功时的执行成功次数。
1.3 启动
Keepalived配置完成后,在Master节点和Backup节点上使用以下命令开启Keepalived服务。
systemctl start keepalived
如果需要设置开机启动,则执行以下命令。
systemctl enable keepalived
2. HAProxy 安装配置
2.1 安装
HAProxy支持源码安装,同时也可以通过不同操作系统安装工具进行安装,本文以CentOS的yum工具为例进行安装介绍,分别在两台已安装并配置好kkeepalived的服务器上执行以下命令进行安装。
yum install -y haproxy
2.2 基本配置
yum安装后,HAProxy将生成配置文件:/etc/haproxy/haproxy.cfg,利用文本编辑器进行配置修改。
vi /etc/haproxy/haproxy.cfg
全局段定义(global)
全局参数配置将配置于所有HAProxy服务器上。
global
log /dev/log local0 info
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
log设置全局日志配置,语法为log <address>
<facility>
<msglevel>
,上例中指定使用本机上的syslog服务中的local0日志设备,记录日志等级为info的日志。chroot设置HAProxy工作目录,pidfile设置HAProxy的pid文件位置,maxconn设置每个HAProxy进程可用的最大连接数,user及group设置HAProxy进程所属的用户及用户组,daemon关键字表示以守护进程方式运行haproxy。
默认段定义(defaults)
默认段的作用是为后续前端代理及后端代理设置默认值。
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
mode表示HAProxy的工作模式,设置tcp时为4层模式,设置http时为7层模式。log设置日志输出方式,配置为global表示将采用全局段log的配置。
option httplog关键字表示记录HTTP详细日志,包括HTTP请求、session状态、连接数等。
option dontlognull关键字表示日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器或者监控系统为了探测该服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描端口是否在监听或开放等动作被称为空连接,官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要设置该参数,因为设置后互联网上的恶意扫描或其他动作就不会被记录下来。
option http-server-close关键字表示每次请求完毕后主动关闭HTTP通道。
option forwardfor关键字表示应用程序想记录发起请求的客户端的IP地址,需要在HAProxy上配置此选项,这样HAProxy会把客户端的IP信息发送给服务器,在HTTP请求中添加"X-Forwarded-For"字段启用 X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获取到客户端的真实IP。
option redispatch关键字表示当使用了cookie时,HAProxy将会将其请求的后端服务器信息插入到cookie中,以保证会话的持久性,如果后端的服务器服务不可用,但客户端的cookie是不会刷新的,设置此参数会将客户的请求强制定向到另外一个后端服务器上,以保证服务的正常。
retries定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为不可用。
timeout为前缀的关键字指定了一些关于请求、连接、响应的最大超时时间,单位默认为毫秒,也可以加入后缀s(秒),m(分钟),h(小时),d(天)来指定。http-request设置HTTP请求超时时长,queue设置一个请求在队列里的超时时间,connect设置最大与服务端建立连接的时长,client设置客户端最大非活动时长,server设置服务端最大非活动时长,http-keep-alive设置最大等待新请求的空闲时长,check设置检测超时时长。
前端代理定义(frontend)
前端代理配置定义一个服务监听,用于接收用户请求并将请求转发给后端代理,可以定义多个前端代理。
frontend main
mode http
bind :80
default_backend nginx
frontend前端代理配置段定义一组前端服务并启动服务监听,同时设置代理名称。mode设置工作模式,如果此参数未被设定则引用默认配置段配置的模式。bind设置监听地址及端口,地址为空或者表示绑定至所有服务器的网络接口。default_backend指定默认后端代理进行流量转发。
后端代理定义(backend)
用于接收前端代理请求并根据设置的负载均衡策略将流量转发至指定后端并对后端执行健康检查,一个前端可以指向多个后端;同时一个后端可以被多个调用。
backend nginx
mode http
balance roundrobin
server web1 host1:80 check inter 3s rise 1 fall 2
server web2 host2:80 check
backend后端代理配置段定义一组后端服务器,同时设置代理名称。mode设置工作模式如果此参数未被设定则引用默认配置段的模式。balance设置后端负载均衡转发策略,策略取值请下面表。
server配置了相应的后端服务集群地址,是真实的服务器,一个backend对应一个或者多个实体服务器。配置依次为节点名称、节点IP和端口、启用四层健康检查,在上述示例中web1服务器还设定了检查的相关参数表示每3秒(inter)检查一次,执行两次(fall)失败认为故障,执行一次(rise)成功即为服务可用。
2.3 启动
HAProxy配置完成后,使用以下命令开启HAProxy服务。
systemctl start haproxy
如果需要设置开机启动,则执行以下命令。
systemctl enable haproxy
修改配置文件后可以通过刷新配置的方式热加载配置。
systemctl reload haproxy
2.4会话保持
HAProxy在会话保持功能上可以分为四层会话保持和七层会话保持。四层会话保持是基于源地址的会话保持,是指HAProxy在负载均衡时根据访问请求的源地址作为判断关联会话的依据,对于同一IP地址的所有访问请求在作负载均衡时均会被保持到后端的同一台服务器上。七层会话保持是基于cookie的会话保持,当客户端HTTP请求进入HAProxy时,根据负载均衡策略选择后端的一台服务器,后端服务器将HTTP响应返回HAProxy,此时HAproxy会插入该服务器的cookie并将插入cookie的HTTP响应返回至客户端,当该客户端再次发出请求时,带有上次插入cookie的HTTP请求进入HAProxy,HAProxy解析出cookie中服务器信息并将请求发送至相同的后端服务器。
四层会话保持的配置方式实际只需要将配置文件中后端代理段的负载均衡策略设置为基于源地址哈希并将工作模式设置为tcp即可,配置文件如下。
backend nginx
mode tcp
balance source
server web1 10.230.150.68:80 check cookie web1
server web3 10.230.150.70:80 check cookie web3
七层会话保持配置方式则需要在配置文件后端代理段中设置cookie并确保工作模式为http,配置文件如下。
backend nginx
mode http
balance roundrobin
cookie WEBSRV insert indirect nocache
server web1 10.230.150.68:80 check cookie web1
server web3 10.230.150.70:80 check cookie web3
以上配置文件中的cookie设置了以WEBSRV为名称的cookie,然后在server配置中分别定义了不同的cookie值,通过浏览器访问HAProxy前端代理地址可以看到该cookie,利用该cookie实现会话保持,如下图所示。
四、内核优化
vim /etc/sysctl.conf
#开启重用。允许将TIME-WAITsockets重用于新的TCP连接,默认0,表示关闭;
net.ipv4.tcp_tw_reuse = 1
#用于向外连接的端口范围。缺省情况下很小
net.ipv4.ip_local_port_range = 1024 65535
#SYN队列长度,记录尚未收到客户端确认信息的连接请求的最大值。默认为1024,加大队列长度可容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_syn_backlog = 10240
#表示系统同时保持TIME_WAIT最大数量,如果超过,TIME_WAIT将立刻被清除并打印警告信息。默认180000,此项参数可控制TIME_WAIT 最大数量
net.ipv4.tcp_max_tw_buckets = 5000
#系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上,如超过,连接将即刻被复位并打印警告信息,这个限制仅是为防止简单的DoS攻击,不能过分依靠它或人为减小这个值,更应该增加这个值(如果增加内存后)
net.ipv4.tcp_max_orphans = 3276800
#为打开对端的连接,内核需发送个SYN并附带个回应前一个SYN的ACK。即三次握手中的第二次握手。该设置决定内核放弃连接前发SYN+ACK包的数量。
net.ipv4.tcp_synack_retries = 3
#如web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而 nginx 定义的 NGX_LISTEN_BACKLOG 默认511,所以有必要调整这个值。
net.core.somaxconn = 32768
sysctl -p
五、总结
1. LVS、Nginx、Haproxy 的区别
负载均衡性能 [硬件负载F5 >] LVS 最好 > Haproxy 其次 > Nginx 弱于其它两种
支持的代理类型 LVS基于系统内核实现的负载均衡,只能支持4层代理的IP转发(不支持正则)Haproxy和Nginx基于应用程序实现的负载均衡,都能支持4层和7层代理转发(支持正则)
支持的健康检查方式 LVS支持对端口和URL进行检查,Nginx只支持对端口的检查,Haproxy支持端口、URL、脚本等多种检查方式
2. Haproxy 调度算法原理(8种)
调度算法 | 中文含义 |
---|---|
roundrobin | 轮询 |
static-rr | 加权轮询 |
leastconn | 最小连接数 |
source | 根据源地址哈希 |
uri | 根据URL哈希 |
url_param | 根据URL参数哈希 |
hdr(name) | 根据请求头哈希 |
rdp-cookie(name) | 根据cookie哈希 |