最近发现 F5 这样的负载均衡设备可能请求时间会出现抖动现象,最长的请求经常可以达到好几秒。考虑到 F5 会对所有数据进行 NAT ,有可能处理能力不足,打算研究一下 LVS 会不会有类似现象。

小知识:什么是 LVS?

LVS 是 Linux Virtual Server 的缩写,是章文嵩主持开发的基于 Linux 的类似 F5 这样的连接管理软件,它将接收到的数据包进行部分修改后,发送给后端多台服务器,实现了多台服务器共享同一个 IP 的效果,通过一些配套的 HA 软件互相监测,可以自动剔除失败的后端结点,或者启动备份的前端转发系统。为了避免所有数据都经过前端转发结点造成瓶颈,LVS 在类似  F5 那样的 NAT 模式之上,还提供了隧道模式和直接路由模式两种配置方式,后两种方式巧妙的利用了 Linux kernel 的路由处理逻辑和交换机的工作原理,使得只有入流量经过转发结点,出流量直接从后端处理结点返回给用户。一般 WWW  服务都是出流量远大于入流量,这种情况下面 LVS 可以获得很好的性能。

LVS 的直接路由模式配置:

LVS 直接路由模式是性能最好的一种方式,他的工作原理是这样的,  服务入口 IP 配置在转发结点上面,这样入流量都会被交换机送到转发结点上面,转发结点上面 LVS 模块会处理入流量数据,跟踪其中的TCP连接,将这些 TCP  连接数据分发到多台后端上面,后端的 Linux 系统在自己的lo设备上面也绑定服务入口 IP ,并打开 IP 转发,最后还要加一条路由,将服务入口 IP 指向 lo 设备上面,从前端发送过来的数据被后端收到以后,后端机器按照路由转发数据, 数据就被转发到 lo 设备上面,因为 lo 设备绑定了服务入口 IP, 这些数据就被后端机器的协议栈捡起来了。后端机器处理完数据以后,将数据发送到外网路由器上面直接发送回客户端。

从以上过程可以看出来,LVS 的直接路由模式有这些特点:

1: 前端处理逻辑比起 NAT 模式来要简单一些,只需要跟踪连接,并修改 mac 就可以。

2: 依赖于后端操作系统的路由功能,

3: 后端机器要和前端机器处于同一局域网内,否则前端无法通过不修改网络层数据来将数据发送给后端。

LVS 的简单配置方法,假设公共服务 IP 是 10.0.0.10, 前端机器是  10.0.0.11, 后端机器是 10.0.0.12-14, 前端机器上面已经安装了 ipvsadm 包,内核也已经编译支持 LVS, 配置方法如下:

# 打开前端机器的 ip_forward , 这个是 LVS 需要的
echo 1 > /proc/sys/net/ipv4/ip_forward
# 添加一个位于公网 IP 80 端口的虚拟服务, 负载均衡协议是 weighted lease connection
ipvsadm -A -t 10.0.0.10:80 -s wlc
# 添加后端 IP 们, -g 表明使用的是 direct routing 模式
ipvsadm -a -t 10.0.0.10:80 -r 10.0.0.12 -g
ipvsadm -a -t 10.0.0.10:80 -r 10.0.0.13 -g
ipvsadm -a -t 10.0.0.10:80 -r 10.0.0.14 -g

后端机器上面

# 打开 ip_forward
echo 1 > /proc/sys/net/ipv4/ip_forward
# 防止后端机器应答虚拟 IP 的 arp 信息
echo ‘2’ > /proc/sys/net/ipv4/conf/lo/arp_announce
echo ‘1’ > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo ‘2’ > /proc/sys/net/ipv4/conf/all/arp_announce
echo ‘1’ > /proc/sys/net/ipv4/conf/all/arp_ignore

# 在 lo:0 上面配置虚拟 IP
ifconfig lo:0 10.0.0.10 netmask 255.255.255.255
# 增加到 lo:0 的路由
route add -host 10.0.0.10 dev lo:0
如此 LVS 应该就工作正常了,可惜用 ab 的测试结果并不是非常好,后端用 squid 来做服务,用相同的压力压在单台 squid 上面一点都没有抖动现象,通过 LVS 打,马上就能看出来抖动。sigh