当前位置: 首页>移动开发>正文

M63.第十八周作业

1、简述keepalived工作原理

1.Keepalived 定义

Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障。一个LVS服务会有2台服务器运行Keepalived,一台为主服务器(MASTER),一台为备份服务器(BACKUP),但是对外表现为一个虚拟IP,主服务器会发送特定的消息给备份服务器,当备份服务器收不到这个消息的时候,即主服务器宕机的时候, 备份服务器就会接管虚拟IP,继续提供服务,从而保证了高可用性。Keepalived是VRRP的完美实现,因此在介绍keepalived之前,先介绍一下VRRP的原理。

2.VRRP 协议简介

在现实的网络环境中,两台需要通信的主机大多数情况下并没有直接的物理连接。对于这样的情况,它们之间路由怎样选择?主机如何选定到达目的主机的下一跳路由,这个问题通常的解决方法有二种:

在主机上使用动态路由协议(RIP、OSPF等)

在主机上配置静态路由

很明显,在主机上配置动态路由是非常不切实际的,因为管理、维护成本以及是否支持等诸多问题。配置静态路由就变得十分流行,但路由器(或者说默认网关default gateway)却经常成为单点故障。VRRP的目的就是为了解决静态路由单点故障问题,VRRP通过一竞选(election)协议来动态的将路由任务交给LAN中虚拟路由器中的某台VRRP路由器。

3.VRRP 工作机制

在一个VRRP虚拟路由器中,有多台物理的VRRP路由器,但是这多台的物理的机器并不能同时工作,而是由一台称为MASTER的负责路由工作,其它的都是BACKUP,MASTER并非一成不变,VRRP让每个VRRP路由器参与竞选,最终获胜的就是MASTER。MASTER拥有一些特权,比如,拥有虚拟路由器的IP地址,我们的主机就是用这个IP地址作为静态路由的。拥有特权的MASTER要负责转发发送给网关地址的包和响应ARP请求。

VRRP通过竞选协议来实现虚拟路由器的功能,所有的协议报文都是通过IP多播(multicast)包(多播地址224.0.0.18)形式发送的。虚拟路由器由VRID(范围0-255)和一组IP地址组成,对外表现为一个周知的MAC地址。所以,在一个虚拟路由 器中,不管谁是MASTER,对外都是相同的MAC和IP(称之为VIP)。客户端主机并不需要因为MASTER的改变而修改自己的路由配置,对客户端来说,这种主从的切换是透明的。

在一个虚拟路由器中,只有作为MASTER的VRRP路由器会一直发送VRRP通告信息(VRRPAdvertisement message),BACKUP不会抢占MASTER,除非它的优先级(priority)更高。当MASTER不可用时(BACKUP收不到通告信息), 多台BACKUP中优先级最高的这台会被抢占为MASTER。这种抢占是非常快速的(<1s),以保证服务的连续性。由于安全性考虑,VRRP包使用了加密协议进行加密。

4.VRRP 工作流程

(1).初始化:

路由器启动时,如果路由器的优先级是255(最高优先级,路由器拥有路由器地址),要发送VRRP通告信息,并发送广播ARP信息通告路由器IP地址对应的MAC地址为路由虚拟MAC,设置通告信息定时器准备定时发送VRRP通告信息,转为MASTER状态;否则进入BACKUP状态,设置定时器检查定时检查是否收到MASTER的通告信息。

(2).Master

设置定时通告定时器;

用VRRP虚拟MAC地址响应路由器IP地址的ARP请求;

转发目的MAC是VRRP虚拟MAC的数据包;

如果是虚拟路由器IP的拥有者,将接受目的地址是虚拟路由器IP的数据包,否则丢弃;

当收到shutdown的事件时删除定时通告定时器,发送优先权级为0的通告包,转初始化状态;

如果定时通告定时器超时时,发送VRRP通告信息;

收到VRRP通告信息时,如果优先权为0,发送VRRP通告信息;否则判断数据的优先级是否高于本机,或相等而且实际IP地址大于本地实际IP,设置定时通告定时器,复位主机超时定时器,转BACKUP状态;否则的话,丢弃该通告包;

(3).Backup

设置主机超时定时器;

不能响应针对虚拟路由器IP的ARP请求信息;

丢弃所有目的MAC地址是虚拟路由器MAC地址的数据包;

不接受目的是虚拟路由器IP的所有数据包;

当收到shutdown的事件时删除主机超时定时器,转初始化状态;

主机超时定时器超时的时候,发送VRRP通告信息,广播ARP地址信息,转MASTER状态;

收到VRRP通告信息时,如果优先权为0,表示进入MASTER选举;否则判断数据的优先级是否高于本机,如果高的话承认MASTER有效,复位主机超时定时器;否则的话,丢弃该通告包;

5.ARP查询处理

当内部主机通过ARP查询虚拟路由器IP地址对应的MAC地址时,MASTER路由器回复的MAC地址为虚拟的VRRP的MAC地址,而不是实际网卡的 MAC地址,这样在路由器切换时让内网机器觉察不到;而在路由器重新启动时,不能主动发送本机网卡的实际MAC地址。如果虚拟路由器开启的ARP代理 (proxy_arp)功能,代理的ARP回应也回应VRRP虚拟MAC地址;

2、编译安装haproxy

环境准备

由于CentOS7 之前版本自带的lua版本比较低并不符合HAProxy要求的lua最低版本(5.3)的要求,因此需要编译安装较新版本的lua环境,然后才能编译安装HAProxy,过程如下:

#当前系统版本

[root@centos7 ~]#lua -v

Lua 5.1.4? Copyright (C) 1994-2008 Lua.org, PUC-Rio

#安装基础命令及编译依赖环境

[root@centos7 ~]#yum install gcc readline-devel -y

[root@centos7 ~]#tar xvf lua-5.4.4.tar.gz -C /usr/local/src

[root@centos7 ~]#cd /usr/local/src/lua-5.4.4/

[root@centos7 lua-5.4.4]#make linux test

#查看编译安装的版本

[root@centos7 lua-5.4.4]#src/lua -v

Lua 5.4.4? Copyright (C) 1994-2022 Lua.org, PUC-Rio

1编译安装HAProxy

#HAProxy 2.0以上版本编译参数:

[root@centos7 ~]#yum -y install gcc openssl-devel pcre-devel systemd-devel

[root@centos7 ~]#tar xvf haproxy-2.4.15.tar.gz -C /usr/local/src

[root@centos7 ~]#cd /usr/local/src/haproxy-2.4.15/

#查看安装方法

[root@centos7 haproxy-2.4.15]#less INSTALL

[root@centos7 haproxy-2.4.15]#less Makefile

#参考INSTALL文件进行编译安装

[root@centos7 haproxy-2.4.15]#make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.4.4/src/ LUA_LIB=/usr/local/src/lua-5.4.4/src/

[root@centos7 haproxy-2.4.15]#make install PREFIX=/apps/haproxy

[root@centos7 haproxy-2.4.15]#ln -s /apps/haproxy/sbin/haproxy /usr/sbin/

#查看生成的文件

[root@centos7 haproxy-2.4.15]#tree /apps/haproxy/

/apps/haproxy/

├── doc

│? └── haproxy

│? ? ? ├── 51Degrees-device-detection.txt

│? ? ? ├── architecture.txt

│? ? ? ├── close-options.txt

│? ? ? ├── configuration.txt

│? ? ? ├── cookie-options.txt

│? ? ? ├── DeviceAtlas-device-detection.txt

│? ? ? ├── intro.txt

│? ? ? ├── linux-syn-cookies.txt

│? ? ? ├── lua.txt

│? ? ? ├── management.txt

│? ? ? ├── netscaler-client-ip-insertion-protocol.txt

│? ? ? ├── network-namespaces.txt

│? ? ? ├── peers.txt

│? ? ? ├── peers-v2.0.txt

│? ? ? ├── proxy-protocol.txt

│? ? ? ├── regression-testing.txt

│? ? ? ├── seamless_reload.txt

│? ? ? ├── SOCKS4.protocol.txt

│? ? ? ├── SPOE.txt

│? ? ? └── WURFL-device-detection.txt

├── sbin

│? └── haproxy

└── share

? ? └── man

? ? ? ? └── man1

? ? ? ? ? ? └── haproxy.1

6 directories, 22 files

1.1验证HAProxy版本


#验证HAProxy版本:

[root@centos7 haproxy-2.4.15]#which haproxy

/usr/sbin/haproxy

[root@centos7 haproxy-2.4.15]#haproxy -v

HAProxy version 2.4.15-7782e23 2022/03/14 - https://haproxy.org/

Status: long-term supported branch - will stop receiving fixes around Q2 2026.

Known bugs: http://www.haproxy.org/bugs/bugs-2.4.15.html

Running on: Linux 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64

#大写-V选项显示版本和帮助用法

[root@centos7 haproxy-2.4.15]#haproxy -V

HAProxy version 2.4.15-7782e23 2022/03/14 - https://haproxy.org/

Status: long-term supported branch - will stop receiving fixes around Q2 2026.

Known bugs: http://www.haproxy.org/bugs/bugs-2.4.15.html

Running on: Linux 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64

Usage : haproxy [-f <cfgfile|cfgdir>]* [ -vdVD ] [ -n <maxconn> ] [ -N <maxpconn> ]

? ? ? ? [ -p <pidfile> ] [ -m <max megs> ] [ -C <dir> ] [-- <cfgfile>*]

? ? ? ? -v displays version ; -vv shows known build options.

? ? ? ? -d enters debug mode ; -db only disables background mode.

? ? ? ? -dM[<byte>] poisons memory with <byte> (defaults to 0x50)

? ? ? ? -V enters verbose mode (disables quiet mode)

? ? ? ? -D goes daemon ; -C changes to <dir> before loading files.

? ? ? ? -W master-worker mode.

? ? ? ? -Ws master-worker mode with systemd notify support.

? ? ? ? -q quiet mode : don't display messages

? ? ? ? -c check mode : only check config files and exit

? ? ? ? -n sets the maximum total # of connections (uses ulimit -n)

? ? ? ? -m limits the usable amount of memory (in MB)

? ? ? ? -N sets the default, per-proxy maximum # of connections (0)

? ? ? ? -L set local peer name (default to hostname)

? ? ? ? -p writes pids of all children to this file

? ? ? ? -de disables epoll() usage even when available

? ? ? ? -dp disables poll() usage even when available

? ? ? ? -dS disables splice usage (broken on old kernels)

? ? ? ? -dG disables getaddrinfo() usage

? ? ? ? -dR disables SO_REUSEPORT usage

? ? ? ? -dL dumps loaded object files after config checks

? ? ? ? -dr ignores server address resolution failures

? ? ? ? -dV disables SSL verify on servers side

? ? ? ? -dW fails if any warning is emitted

? ? ? ? -dD diagnostic mode : warn about suspicious configuration statements

? ? ? ? -sf/-st [pid ]* finishes/terminates old pids.

? ? ? ? -x <unix_socket> get listening sockets from a unix socket

? ? ? ? -S <bind>[,<bind options>...] new master CLI

1.2准备HAProxy启动文件

#创建service文件

[root@centos7 haproxy-2.4.15]#vim /usr/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 -c -q

ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid

ExecReload=/bin/kill -USR2 $MAINPID

LimitNOFILE=100000

[Install]

WantedBy=multi-user.target

[root@centos7 haproxy-2.4.15]#systemctl daemon-reload

1.3配置文件

#创建自定义的配置文件

[root@centos7 haproxy-2.4.15]#mkdir /etc/haproxy

[root@centos7 haproxy-2.4.15]#vim /etc/haproxy/haproxy.cfg

global

? ? maxconn 100000

? ? chroot /apps/haproxy

? ? stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin

? ? #uid 99

? ? #gid 99

? ? user haproxy

? ? group haproxy

? ? daemon

? ? #nbproc 4

? ? #cpu-map 1 0

? ? #cpu-map 2 1

? ? #cpu-map 3 2

? ? #cpu-map 4 3

? ? pidfile /var/lib/haproxy/haproxy.pid

? ? log 127.0.0.1 local2 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 haadmin:123456

listen web_port

? ? bind 10.0.0.7:80

? ? mode http

? ? log global

? ? server web1 127.0.0.1:8080 check inter 3000 fall 2 rise 5

1.4启动 haproxy

#准备socket文件目录

[root@centos7 haproxy-2.4.15]#mkdir /var/lib/haproxy

#设置用户和目录权限

[root@centos7 haproxy-2.4.15]#useradd -r -s /sbin/nologin -d /var/lib/haproxy haproxy

[root@centos7 haproxy-2.4.15]#systemctl enable --now haproxy

1.5验证 haproxy 状态

[root@centos7 haproxy-2.4.15]#systemctl status haproxy

● haproxy.service - HAProxy Load Balancer

? Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)

? Active: active (running) since Sun 2022-04-17 14:10:51 CST; 1min 56s ago

? Process: 3503 ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q (code=exited, status=0/SUCCESS)

Main PID: 3506 (haproxy)

? CGroup: /system.slice/haproxy.service

? ? ? ? ? ├─3506 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid

? ? ? ? ? └─3509 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid

Apr 17 14:10:51 centos7 systemd[1]: Starting HAProxy Load Balancer...

Apr 17 14:10:51 centos7 systemd[1]: Started HAProxy Load Balancer.

Apr 17 14:10:51 centos7 haproxy[3506]: [NOTICE]? (3506) : New worker #1 (3509) forked

Apr 17 14:10:51 centos7 haproxy[3506]: [WARNING]? (3509) : Server web_port/web1 is DOWN, reason: Layer4 connec...ueue.

Apr 17 14:10:51 centos7 haproxy[3506]: [NOTICE]? (3509) : haproxy version is 2.4.15-7782e23

Apr 17 14:10:51 centos7 haproxy[3506]: [NOTICE]? (3509) : path to executable is /usr/sbin/haproxy

Apr 17 14:10:51 centos7 haproxy[3506]: [ALERT]? ? (3509) : proxy 'web_port' has no server available!

Hint: Some lines were ellipsized, use -l to show in full.

[root@centos7 haproxy-2.4.15]#pstree -p |grep haproxy

? ? ? ? ? |-haproxy(3506)---haproxy(3509)---{haproxy}(3510)

1.6查看haproxy的状态页面

#浏览器访问:http://10.0.0.7:9999/haproxy-status

M63.第十八周作业,第1张

3、总结haproxy各调度算法的实现方式及其应用场景

HAProxy调度算法

HAProxy通过固定参数 balance 指明对后端服务器的调度算法,该参数可以配置在listen或backend选项中 。

HAProxy的调度算法分为静态和动态调度算法,但是有些算法可以根据参数在静态和动态算法中相互转换。

1 静态算法

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

1.1 static-rr

static-rr:基于权重的轮询调度,该算法与轮循算法相似,只是它是静态的,这意味着动态更改服务器的权重不会产生任何影响。不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的 wrr

#代码实现

[root@haproxy ~]#cat /etc/haproxy/conf.d/test.cfg

listen ha1_web_80

? ? bind 10.0.0.7:80

? ? balance static-rr

? ? server rs1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

? ? server rs2 10.0.0.27:80 weight 2 check inter 3000 fall 2 rise 5

? ? server local 127.0.0.1:80 backup

[root@haproxy ~]#systemctl reload haproxy.service

#测试

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.27


1.2 first

first:根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务(一旦服务器达到其 maxconn 值,使用下一个服务器)。该算法的目的是始终使用最小的服务器数量,以便可以关闭额外的服务器在非密集时间。因此会忽略服务器的权重设置,此方式使用较少

不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效,该算法忽略服务器权重。

#代码实现

maxconn <maxconn> #当前后端server的最大并发连接数

[root@haproxy ~]#cat /etc/haproxy/conf.d/test.cfg

listen ha1_web_80

? ? bind 10.0.0.7:80

? ? balance first

? ? server rs1 10.0.0.17:80 maxconn 1 weight 1 check inter 3000 fall 2 rise 5

? ? server rs2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

? ? server local 127.0.0.1:80 backup

[root@haproxy ~]#systemctl reload haproxy.service

#测试,同时运行下面命令,观察结果

[root@client ~]#while true;do curl http://10.0.0.7/index.html ; sleep 0.1;done

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.17


2 动态算法

动态算法:基于后端服务器状态进行调度适当调整,新请求将优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启。

2.1 roundrobin

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

#代码实现

[root@haproxy ~]#cat /etc/haproxy/conf.d/test.cfg

listen ha1_web_80

? ? bind 10.0.0.7:80

? ? balance roundrobin

? ? server rs1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

? ? server rs2 10.0.0.27:80 weight 2 check inter 3000 fall 2 rise 5

? ? server local 127.0.0.1:80 backup

[root@haproxy ~]#systemctl reload haproxy.service

#测试

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.17

2.2 leastconn

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

#代码实现

[root@haproxy ~]#cat /etc/haproxy/conf.d/test.cfg

listen ha1_web_80

? ? bind 10.0.0.7:80

? ? balance leastconn

? ? server rs1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

? ? server rs2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

? ? server local 127.0.0.1:80 backup

[root@haproxy ~]#systemctl reload haproxy.service

#测试

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.27

2.3 random

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

#代码实现

[root@haproxy ~]#cat /etc/haproxy/conf.d/test.cfg

listen ha1_web_80

? ? bind 10.0.0.7:80

? ? balance random

? ? server rs1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

? ? server rs2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

? ? server local 127.0.0.1:80 backup

[root@haproxy ~]#systemctl reload haproxy.service

#测试

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.27

[root@client ~]#curl 10.0.0.7

10.0.0.17

3 其他算法

其它算法既可作为静态算法,又可以通过选项成为动态算法

3.1 source

源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type选项进行更改

这个算法一般是在不插入Cookie的TCP模式下使用,也可给不支持会话cookie的客户提供最好的会话粘性,适用于session会话保持但不支持cookie和缓存的场景

源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash

3.1.1 map-base 取模法

map-based:取模法,对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法

所谓取模运算,就是计算两个数相除之后的余数,10%7=3, 7%4=3

map-based算法:基于权重取模,hash(source_ip)%所有后端服务器相加的总权重

#代码实现

[root@haproxy ~]#cat /etc/haproxy/conf.d/test.cfg

listen ha1_web_80

? ? bind 10.0.0.7:80

? ? balance source

? ? hash-type map-based

? ? server rs1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

? ? server rs2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

? ? server local 127.0.0.1:80 backup

[root@haproxy ~]#systemctl reload haproxy.service

#测试

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.17

3.1.2 一致性 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示意图:后端服务器在线与离线的调度方式

M63.第十八周作业,第2张

#代码实现

[root@haproxy ~]#cat /etc/haproxy/conf.d/test.cfg

listen ha1_web_80

? ? bind 10.0.0.7:80

? ? balance source

? ? hash-type consistent

? ? server rs1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

? ? server rs2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

? ? server local 127.0.0.1:80 backup

[root@haproxy ~]#systemctl reload haproxy.service

#测试

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.17

[root@client ~]#curl 10.0.0.7

10.0.0.17

3.2 uri

基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后,根据最终结果将请求转发到后端指定服务器,这确保了只要没有服务器启动或关闭,相同的URI将始终定向到同一台服务器。适用于后端是缓存服务器场景,以最大限度地提高缓存命中率。默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。

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

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

左半部分:/<path>;<params>

整个uri:/<path>;<params>?<query>#<frag>

#代码实现

[root@rs1 ~]#cd /var/www/html/

[root@rs1 html]#ls

index.html

[root@rs1 html]#for i in {1..10};do echo test$i on 10.0.0.17 > test$i.html;done

[root@rs1 html]#ls

index.html? test1.html? test3.html? test5.html? test7.html? test9.html

test10.html? test2.html? test4.html? test6.html? test8.html

[root@rs2 ~]#cd /var/www/html/

[root@rs2 html]#ls

index.html

[root@rs2 html]#for i in {1..10};do echo test$i on 10.0.0.27 > test$i.html;done

[root@rs2 html]#ls

index.html? test1.html? test3.html? test5.html? test7.html? test9.html

test10.html? test2.html? test4.html? test6.html? test8.html

#uri 一致性hash

[root@haproxy ~]#cat /etc/haproxy/conf.d/test.cfg

listen ha1_web_80

? ? bind 10.0.0.7:80

? ? balance uri

? ? hash-type consistent

? ? server rs1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

? ? server rs2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

? ? server local 127.0.0.1:80 backup

[root@haproxy ~]#systemctl reload haproxy.service

#测试,访问不同的uri,确认可以将用户同样的请求转发至相同的服务器

[root@client ~]#curl 10.0.0.7/test1.html

test1 on 10.0.0.17

[root@client ~]#curl 10.0.0.7/test1.html

test1 on 10.0.0.17

[root@client ~]#curl 10.0.0.7/test1.html

test1 on 10.0.0.17

[root@client ~]#curl 10.0.0.7/test1.html

test1 on 10.0.0.17

[root@client ~]#curl 10.0.0.7/test2.html

test2 on 10.0.0.17

[root@client ~]#curl 10.0.0.7/test3.html

test3 on 10.0.0.27

[root@client ~]#curl 10.0.0.7/test3.html

test3 on 10.0.0.27

[root@client ~]#curl 10.0.0.7/test3.html

test3 on 10.0.0.27

3.3 url_param

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

#假设:

url = http://www.baidu.com/foo/bar/index.php?key=value

#则:

host = "www.baidu.com"

url_param = "key=value"

#代码实现

#url_param一致性hash

[root@haproxy ~]#cat /etc/haproxy/conf.d/test.cfg

listen ha1_web_80

? ? bind 10.0.0.7:80

? ? balance url_param userid

? ? hash-type consistent

? ? server rs1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

? ? server rs2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

? ? server local 127.0.0.1:80 backup

[root@haproxy ~]#systemctl reload haproxy.service

#测试

[root@client ~]#curl 10.0.0.7/test4.html?userid=chen

test4 on 10.0.0.17

[root@client ~]#curl 10.0.0.7/test4.html?userid=chen

test4 on 10.0.0.17

[root@client ~]#curl 10.0.0.7/test4.html?userid=chen

test4 on 10.0.0.17

[root@client ~]#curl 10.0.0.7/test1.html?userid=chen

test1 on 10.0.0.17

[root@client ~]#curl 10.0.0.7/index.html?userid=chen

10.0.0.17

[root@client ~]#curl 10.0.0.7/index.html?userid=zhang

10.0.0.27

[root@client ~]#curl 10.0.0.7/index.html?userid=zhang

10.0.0.27

[root@client ~]#curl 10.0.0.7/index.html?userid=zhang

10.0.0.27

3.4 hdr

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

#代码实现

#hdr 一致性hash

[root@haproxy ~]#cat /etc/haproxy/conf.d/test.cfg

listen ha1_web_80

? ? bind 10.0.0.7:80

? ? balance hdr(User-Agent)

? ? hash-type consistent

? ? server rs1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5

? ? server rs2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5

? ? server local 127.0.0.1:80 backup

[root@haproxy ~]#systemctl reload haproxy.service

#测试

[root@client ~]#curl 10.0.0.7/index.html

10.0.0.17

[root@client ~]#curl 10.0.0.7/test1.html

test1 on 10.0.0.17

[root@client ~]#curl 10.0.0.7/test2.html

test2 on 10.0.0.17

[root@client ~]#curl 10.0.0.7/test3.html

test3 on 10.0.0.17

[root@client ~]#curl -A "IE" 10.0.0.7/test4.html

test4 on 10.0.0.27

[root@client ~]#curl -A "Chrome18" 10.0.0.7/test4.html

test4 on 10.0.0.17

[root@client ~]#curl -A "Chrome28" 10.0.0.7/test4.html

test4 on 10.0.0.27

[root@client ~]#curl -A "firefox" 10.0.0.7/test4.html

test4 on 10.0.0.17

3.5 rdp-cookie

rdp-cookie对windows远程桌面的负载,使用cookie保持会话,默认是静态,也可以通过hash-type

指定map-based和consistent,来定义使用取模法还是一致性hash。

注意:要实现此算法,需要Windows系统支持远程桌面功能。

M63.第十八周作业,第3张

4 算法总结

#静态

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

5 各种算法使用场景

first #使用较少

static-rr #做了session共享的 web 集群

roundrobin

random

leastconn #数据库

source #基于客户端公网 IP 的会话保持

Uri--------------->http #缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯

url_param--------->http #可以实现session保持

hdr #基于客户端请求报文头部做下一步处理

rdp-cookie #基于Windows主机,很少使用

4、使用haproxy的ACL实现基于文件后缀名的动静分离

1 ACL

访问控制列表(ACL,Access Control Lists)是一种基于包过滤的访问控制技术,它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配),即对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行进一步操作,比如允许其通过或丢弃。

1.1 ACL配置选项

acl <aclname> <criterion> [flags] [operator] [<value>]

acl ? 名称 匹配规范 匹配模式 ? 具体操作符 ? 操作对象类型

ACL-Name

#ACL名称,可以使用大字母A-Z、小写字母a-z、数字0-9、冒号:、点.、中横线和下划线,并且严格区分大

小写,比如:my_acl和My_Acl就是两个完全不同的acl

ACL-criterion

定义ACL匹配规范,即:判断条件

path_end : suffix match #请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg

ACL-flags

-i 不区分大小写

1.2 ACL基于文件后缀名实现动静分离

[root@haproxy ~]#vim /etc/haproxy/conf.d/test.cfg

frontend ha1_web_80

? ? bind 10.0.0.7:80

? ? balance roundrobin

###################### acl setting ###############################

? ? acl acl_static path_end -i? .jpg .jpeg .png .gif .css .js .html

? ? acl acl_php path_end -i? ? .php

###################### acl hosts #################################

? ? use_backend static_hosts? ? ? ? ? if acl_static

? ? use_backend php_hosts? ? ? ? ? ? if acl_php

###################### backend hosts #############################

backend static_hosts

? ? server rs2 10.0.0.27:80 check inter 3000 fall 2 rise 5

backend php_hosts

? ? server rs1 10.0.0.17:80 check inter 3000 fall 2 rise 5

[root@haproxy ~]#systemctl reload haproxy.service

#分别在后端两台主机准备相关文件

[root@rs1 html]#pwd

/var/www/html

[root@rs1 html]#echo 10.0.0.17 > test.php

[root@rs2 html]#pwd

/var/www/html

[root@rs2 html]#echo 10.0.0.27 > index.html

#测试

[root@client ~]#curl 10.0.0.7/index.html

10.0.0.27

[root@client ~]#curl 10.0.0.7/test.php

10.0.0.17


https://www.xamrdz.com/mobile/4xs1996812.html

相关文章: