四层负载均衡
以常见的 TCP 应用为例,负载均衡器在接收到第一个来自客户端的 SYN 请求时,会通过设定的负载均衡算法选择一个最佳的后端服务器,同时将报文中目标 IP 地址修改为后端服务器 IP,然后直接转发给该后端服务器,这样一个负载均衡请求就完成了。从这个过程来看,一个 TCP 连接是客户端和服务器直接建立的,而负载均衡器只不过完成了一个类似路由器的转发动作。在某些负载均衡策略中,为保证后端服务器返回的报文可以正确传递给负载均衡器,在转发报文的同时可能还会对报文原来的源地址进行修改。整个过程下图所示。
七层负载均衡
这里仍以常见的 TCP 应用为例,由于负载均衡器要获取到报文的内容,因此只能先代替后端服务器和客户端建立连接,接着,才能收到客户端发送过来的报文内容,然后再根据该报文中特定字段加上负载均衡器中设置的负载均衡算法来决定最终选择的内部服务器。纵观整个过程,七层负载均衡器在这种情况下类似于一个代理服务器。整个过程如下图所示。
对比四层负载均衡和七层负载均衡运行的整个过程,可以看出,在七层负载均衡模式下, 负载均衡器与客户端及后端的服务器会分别建立一次 TCP 连接,而在四层负载均衡模式下, 仅建立一次 TCP 连接。由此可知,七层负载均衡对负载均衡设备的要求更高,而七层负载均衡的处理能力也必然低于四层模式的负载均衡。
二、快速安装 HAProxy 集群软件
1、访问www.haproxy.org下载haproxy源码包,需要翻墙下载
2、编译安装源码包
[root@localhost ~]# tar zxvf haproxy-1.8.13.tar.gz
[root@localhost ~]# cd haproxy-1.8.13/
[root@localhost haproxy-1.8.13]# make TARGET=linux31
####这里需要使用uname -r查看系统版本centos6.X需要使用TARGET=linux26 centos7.x使用linux31
[root@localhost haproxy-1.8.13]# uname -r #查询系统内核版本
3.10.0-862.el7.x86_64
[root@localhost haproxy-1.8.13]# make install PREFIX=/usr/local/haproxy
[root@localhost haproxy-1.8.13]# mkdir /usr/local/haproxy/conf
[root@localhost haproxy-1.8.13]# cp examples/option-http_proxy.cfg /usr/local/haproxy/conf/haproxy.cfg
3、启动haproxy
[root@localhost ~]# /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg
三、HAProxy 基础配置文件详解
HAProxy 配置文件根据功能和用途,主要有 5 个部分组成,但有些部分并不是必须的, 可以根据需要选择相应的部分进行配置。
1、global 部分
用来设定全局配置参数,属于进程级的配置,通常和操作系统配置有关。
2、defaults 部分
默认参数的配置部分。在此部分设置的参数值,默认会自动被引用到下面的 frontend、
backend 和 listen 部分中,因此,如果某些参数属于公用的配置,只需在 defaults 部分添加一次即可。而如果在 frontend、backend 和 listen 部分中也配置了与 defaults 部分一样的参数,那么defaults 部分参数对应的值自动被覆盖。
3、frontend 部分
此部分用于设置接收用户请求的前端虚拟节点。frontend 是在 HAProxy1.3 版本之后才引入的一个组件,同时引入的还有 backend 组件。通过引入这些组件,在很大程度上简化了 HAProxy 配置文件的复杂性。frontend 可以根据 ACL 规则直接指定要使用的后端
4、backend 部分
此部分用于设置集群后端服务集群的配置,也就是用来添加一组真实服务器,以处理前端用户的请求。添加的真实服务器类似于 LVS 中的real server 节点。
5、listen 部分
此部分是 frontend 部分和 backend 部分的结合体。在 HAProxy1.3 版本之前,
HAProxy 的所有配置选项都在这个部分中设置。为了保持兼容性,HAProxy 新的版本仍然保留了 listen 组件的配置方式。目前在 HAProxy 中,两种配置方式任选其一即可。
四、 HAProxy 配置文件详解
global
log 127.0.0.1 local0 info maxconn 4096
user nobody
group nobody
daemon
nbproc 1
pidfile /usr/local/haproxy/logs/haproxy.pid
defaults
mode http
retries 3
timeout connect 10s
timeout client 20s
timeout server 30s
timeout check 5s
frontend www
bind *:80
mode http
option httplog
option forwardfor
option httpclose
log global
default_backend htmpool
backend htmpool
mode http
option redispatch
option abortonclose
balance roundrobin
cookie SERVERID
option httpchk GET /index.php
server web1 10.200.34.181:80 cookie server1 weight 6 check inter 2000 rise 2 fall 3
server web2 10.200.34.182:8080 cookie server2 weight 6 check inter 2000 rise 2 fall
listen admin_stats
bind 0.0.0.0:9188
mode http
log 127.0.0.1
local0 err stats
refresh 30s
stats uri /haproxy-status
stats realm welcome login\ Haproxy
stats auth admin:admin123
stats hide-version
stats admin if TRUE
global配置
log:全局的日志配置,local0 是日志设备,info 表示日志级别。其中日志级别有err、warning、info、debug 四种可选。这个配置表示使用 127.0.0.1 上的 rsyslog 服务中的local0 日志设备,记录日志等级为info。
maxconn:设定每个 haproxy 进程可接受的最大并发连接数,此选项等同于 Linux命令行选项“ulimit -n”。
user/ group:设置运行 haproxy 进程的用户和组,也可使用用户和组的 uid 和gid 值来替代。
daemon:设置 HAProxy 进程进入后台运行。这是推荐的运行模式。
nbproc:设置 HAProxy 启动时可创建的进程数,此参数要求将HAProxy 运行模式设置为“daemon”,默认只启动一个进程。根据使用经验,该值的设置应该小于服务器的 CPU 核数。创建多个进程,能够减少每个进程的任务队列,但是过多的进程可能会导致进程的崩溃。
pidfile:指定 HAProxy 进程的 pid 文件。启动进程的用户必须有访问此文件的权限。
defaults 部分
mode:设置 HAProxy 实例默认的运行模式,有 tcp、http、health 三个可选值。
tcp 模式 | 在此模式下,客户端和服务器端之间将建立一个全双工的连接,不会对七层报文做任何类型的检查,默认为 tcp 模式,经常用于 SSL、SSH、SMTP 等应用。 |
http 模式 | 在此模式下,客户端请求在转发至后端服务器之前将会被深度分析,所有不与 RFC 格式兼容的请求都会被拒绝。 |
health 模式 | 目前此模式基本已经废弃,不在多说。 |
retries:设置连接后端服务器的失败重试次数,连接失败的次数如果超过这里设置的值,HAProxy 会将对应的后端服务器标记为不可用。此参数也可在后面部分进行设置。
timeout connect:设置成功连接到一台服务器的最长等待时间,默认单位是毫秒,但也可以使用其他的时间单位后缀。
timeout client:设置连接客户端发送数据时最长等待时间,默认单位是毫秒,也可以使用其他的时间单位后缀。
timeout server:设置服务器端回应客户度数据发送的最长等待时间,默认单位是毫秒,也可以使用其他的时间单位后缀。
timeout check:设置对后端服务器的检测超时时间,默认单位是毫秒,也可以使用其他的时间单位后缀。
frontend 部分
bind:此选项只能在 frontend 和 listen 部分进行定义,用于定义一个或几个监听的套接字。bind 的使用格式为:bind [<address>:<port_range>] interface <interface>其中,address 为可选选项,其可以为主机名或IP 地址,如果将其设置为“*”或“0.0.0.0”,将监听当前系统的所有 IPv4 地址。port_range 可以是一个特定的 TCP 端口,也可是一个端口范围,小于 1024 的端口需要有特定权限的用户才能使用。interface 为可选选项,用来指定网络接口的名称,只能在 Linux 系统上使用。
option httplog:在默认情况下,haproxy 日志是不记录 HTTP 请求的,这样很不方便 HAProxy 问题的排查与监控。通过此选项可以启用日志记录 HTTP 请求。
option forwardfor:如果后端服务器需要获得客户端的真实 IP,就需要配置此参数。由于 HAProxy 工作于反向代理模式,因此发往后端真实服务器的请求中的客户端 IP 均为 HAProxy 主机的 IP,而非真正访问客户端的地址,这就导致真实服务器端无法记录客户端真正请求来源的 IP,而“X-Forwarded-For”则可用于解决此问题。通过使用“forwardfor”选项,HAProxy 就可以向每个发往后端真实服务器的请求添加“X-Forwarded-For”记录,这样后端真实服务器日志可以通过“X-Forwarded-For”信息来记录客户端来源 IP。
option httpclose:此选项表示在客户端和服务器端完成一次连接请求后,HAProxy 将主动关闭此 TCP 连接。这是对性能非常有帮助的一个参数。
log global:表示使用全局的日志配置,这里的“ global”表示引用在HAProxy 配置文件 global 部分中定义的 log 选项配置格式。
default_backend:#指定默认的后端服务器池,也就是指定一组后端真实服务器,而这些真实服务器组将在 backend 段进行定义。这里的htmpool 就是一个后端服务器组。
backend 部分
option redispatch:此参数用于 cookie 保持的环境中。在默认情况下,HAProxy会将其请求的后端服务器的 serverID 插入到 cookie 中,以保证会话的 SESSION 持久性。而如果后端的服务器出现故障,客户端的 cookie 是不会刷新的,这就出现了问题。此时,如果设置此参数,就会将客户的请求强制定向到另外一个健康的后端服务器上,以保证服务的正常。
option abortonclose:如果设置了此参数,可以在服务器负载很高的情况下, 自动结束掉当前队列中处理时间比较长的链接。
balance:此关键字用来定义负载均衡算法。目前 HAProxy 支持多种负载均衡算法,常用的有如下几种:
roundrobin | 是基于权重进行轮询调度的算法,在服务器的性能分布比较均匀的时候,这是一种最公平、最合理的算法。此算法经常使用。 |
static-rr | 也是基于权重进行轮询的调度算法,不过此算法为静态方法,在运行时调整其服务器权重不会生效。 |
source | 是基于请求源 IP 的算法。此算法先对请求的源 IP 进行 hash 运算, 然后将结果与后端服务器的权重总数相除后转发至某个匹配的后端服务器。这种方式可以使同一个客户端 IP 的请求始终被转发到某特定的后端服务器。 |
leastconn | 此算法会将新的连接请求转发到具有最少连接数目的后端服务器。在会话时间较长的场景中推荐使用此算法,例如数据库负载均衡等。此算法不 适合会话较短的环境中,例如基于 HTTP 的应用。 |
uri | 此算法会对部分或整个 URI 进行 hash 运算,再经过与服务器的总权重相除,最后转发到某台匹配的后端服务器上。 |
uri_param | 此算法会根据 URL 路径中的参数进行转发,这样可保证在后端真实服务器数量不变时,同一个用户的请求始终分发到同一台机器上。 |
hdr(<name>): | 此算法根据 http 头进行转发,如果指定的 http 头名称不存在,则使用 roundrobin 算法进行策略转发。 |
cookie:表示允许向 cookie 插入 SERVERID,每台服务器的 SERVERID 可在下面的 server 关键字中使用 cookie 关键字定义。
option httpchk:此选项表示启用 HTTP 的服务状态检测功能。HAProxy 作为一款专业的负载均衡器,它支持对 backend 部分指定的后端服务节点的健康检查,以保证在后端 backend 中某个节点不能服务时,把从 frotend 端进来的客户端请求分配至 backend 中其他健康节点上,从而保证整体服务的可用性。“option httpchk”的用法如下:
option httpchk <method> <uri> <version> 其中,各个参数的含义如下:
method | 表示 HTTP 请求的方式,常用的有 OPTIONS、GET、HEAD 几种方式。一般的健康检查可以采用 HEAD 方式进行,而不是才采用 GET 方式,这是因为 HEAD 方式没有数据返回,仅检查 Response 的 HEAD 是不是 200 状态。因此相对与 GET 来说,HEAD 方式更快,更简单。 |
uri | 表示要检测的 URL 地址,通过执行此 URL,可以获取后端服务器的运行状态。在正常情况下将返回状态码 200,返回其他状态码均为异常状态。 |
version | 指定心跳检测时的 HTTP 的版本号。 |
server:这个关键字用来定义多个后端真实服务器,不能用于 defaults 和frontend部分。使用格式为:server <name> <address>[:port] [param*] 其中,每个参数含义如下:
check:表示启用对此后端服务器执行健康状态检查。
inter:设置健康状态检查的时间间隔,单位为毫秒。
rise:设置从故障状态转换至正常状态需要成功检查的次数,例如。“rise 2”表示 2 次检查正确就认为此服务器可用。
fall:设置后端服务器从正常状态转换为不可用状态需要检查的次数,例如,“fall 3”表示 3 次检查失败就认为此服务器不可用。
cookie:为指定的后端服务器设定 cookie 值,此处指定的值将在请求入站时被检查,第一次为此值挑选的后端服务器将在后
<name> | 为后端真实服务器指定一个内部名称,随便定义一个即可。 | ||
<address> | 后端真实服务器的 IP 地址或主机名。 | ||
<port> | 指定连接请求发往真实服务器时的目标端口。在未设定时,将使用客户端请求时的同一端口。 | ||
[param*] | 为后端服务器设定的一系参数,可用参数非常多,这里仅介绍常用的一些参数: | ||
check | 表示启用对此后端服务器执行健康状态检查。 | ||
inter | 设置健康状态检查的时间间隔,单位为毫秒。 | ||
rise | 设置从故障状态转换至正常状态需要成功检查的次数,例如。“rise 2”表示 2 次检查正确就认为此服务器可用。 | ||
fall | 设置后端服务器从正常状态转换为不可用状态需要检查的次数,例如,“fall 3”表示 3 次检查失败就认为此服务器不可用。 | ||
cookie | 为指定的后端服务器设定 cookie 值,此处指定的值将在请求入站时被检查,第一次为此值挑选的后端服务器将在后续的请求中一直被选中,其目的在于实现持久连接的功能。上面 的“cookie server1”表示 web1 的 serverid 为 server1。同理, “cookie server2”表示 web2 的 serverid 为 server2。 | ||
weight | 设置后端真实服务器的权重,默认为 1,最大值为 256。设置为 0 表示不参与负载均衡。 | ||
backup | 设置后端真实服务器的备份服务器,仅仅在后端所有真实服务器均不可用的情况下才启用。 |
listen 部分
这个部分通过listen 关键字定义了一个名为“admin_stats”的实例,其实就是定义了一个 HAProxy 的监控页面,每个选项的含义如下:
stats refresh:设置 HAProxy 监控统计页面自动刷新的时间。
stats uri:设置 HAProxy 监控统计页面的URL 路径,可随意指定。例如、指定“stats uri /haproxy-status”,就可以过 http://IP:9188/haproxy-status 查看。
stats realm:设置登录 HAProxy 统计页面时密码框上的文本提示信息。
stats auth:设置登录 HAProxy 统计页面的用户名和密码。用户名和密码通过冒号分割。可为监控页面设置多个用户名和密码,每行一个。
stats hide-version:用来隐藏统计页面上 HAProxy 的版本信息。
stats admin if TRUE:通过设置此选项,可以在监控页面上手工启用或禁用后端真实服务器,仅在 haproxy1.4.9 以后版本有效。
完整的haproxy配置文件
global
log 127.0.0.1 local0 info
maxconn 4096
user nobody
group nobody
daemon
nbproc 1
pidfile /usr/local/haproxy/logs/haproxy.pid
defaults
mode http
retries 3
timeout connect 10s
timeout client 20s
timeout server 30s
timeout check 5s
frontend www
bind *:80
mode http
option httplog
option forwardfor
option httpclose
log global
#acl host_www hdr_dom(host) -i www.zb.com
#acl host_img hdr_dom(host) -i img.zb.com
#use_backend htmpool if host_www
#use_backend imgpool if host_img
default_backend htmpool
backend htmpool
mode http
option redispatch
option abortonclose
balance static-rr
cookie SERVERID
option httpchk GET /index.jsp
server 237server 192.168.81.237:8080 cookie server1 weight 6 check inter 2000 rise 2 fall 3
server iivey234 192.168.81.234:8080 cookie server2 weight 3 check inter 2000 rise 2 fall 3
backend imgpool
mode http
option redispatch
option abortonclose
balance static-rr
cookie SERVERID
option httpchk GET /index.jsp
server host236 192.168.81.236:8080 cookie server1 weight 6 check inter 2000 rise 2 fall 3
listen admin_stats
bind 0.0.0.0:9188
mode http
log 127.0.0.1 local0 err
stats refresh 30s
stats uri /haproxy-status
stats realm welcome login\ Haproxy
stats auth admin:admin123
stats hide-version
stats admin if TRUE
五、haproxy 解决集群 session 共享问题
Haproxy 二种方法保持客户端 session 一致
1、用户 IP 识别
haroxy 将用户 IP 经过 hash 计算后 指定到固定的真实服务器上(类似于 nginx 的 IP hash 指令)
配置指令: balance source
backend htmpool
mode http
option redispatch
option abortonclose
balance source
cookie SERVERID
option httpchk GET /index.jsp
server 237server 192.168.81.237:8080 cookie server1 weight 6 check inter 2000 rise 2 fall 3
server iivey234 192.168.81.234:8080 cookie server2 weight 3 check inter 2000 rise 2 fall 3
2、 cookie 识别
haproxy 将WEB 服务端发送给客户端的 cookie 中插入(或添加加前缀)haproxy 定义的后端的服务器COOKIE ID。
配置指令例举 cookie SESSION_COOKIE insert indirect nocache
backend htmpool
mode http
option redispatch
option abortonclose
balance static-rr
cookie SERVERID #cookie参数
option httpchk GET /index.jsp
server 237server 192.168.81.237:8080 cookie server1 weight 6 check inter 2000 rise 2 fall 3 #server里面的cookie参数
server iivey234 192.168.81.234:8080 cookie server2 weight 3 check inter 2000 rise 2 fall 3 #server里面的cookie参数