背景

由于公司特性,我们对文件传输压测较多。通常在高并发的情况下,单机的网卡流量会存在瓶颈,我们机器的配置是千兆网卡,单机最多能够同时处理 1G 左右的网络带宽。由于物理层面的限制,单机的 mock 服务无法支撑我们的压测需求。所以我们需要找到一个方案,能够支撑我们的需求。

方案:

首先我们很容易想到的是,对 mock 服务做一个负载均衡,将流量分散至多台机器,能够无限横向扩展,从而解决网卡流量成为瓶颈的问题。
我们初期调研了常见的 nginx 负载均衡,发现 nginx 作为负载均衡器无法满足我我们的需求。故而采取 lvs 负载均衡的方式做我们负载转发器。

nginx 负载均衡

Nginx 作为一个基于 C 实现的高性能 Web 服务器,可以通过系列算法解决上述的负载均衡问题。并且由于它具有高并发、高可靠性、高扩展性、开源等特点,成为开发人员常用的反向代理工具。

缺点

所有流量都会经过 nginx 所在的服务器,导致 nginx 成为流量吞吐的瓶颈,无法满足我们的需求。

LVS 负载均衡

什么是 LVS

LVS: 是 Linux Virtual Server 的简写,也就是 Linux 虚拟服务器,是一个虚拟的服务器集群系统,本项目在 1998 年 5 月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。官方网站 :http://www.linuxvirtualserver.org LVS 实际上相当于基于 IP 地址的虚拟化应用,为基于 IP 地址和内容请求分发的负载均衡提出了高效的解决方法,现在 LVS 已经是 Linux 内核标准的一部分。

工作模式

基于 NAT 的 LVS 模式负载均衡

在 NAT 模式下,LVS 负载均衡器作为客户端和后端服务器之间的中间人。当客户端请求到达负载均衡器时,负载均衡器会将请求的目标地址和端口转换为后端服务器的实际地址和端口,然后将请求转发给后端服务器处理。后端服务器将响应返回给负载均衡器,负载均衡器再将响应转发给客户端。由于转换地址的过程,客户端认为直接与负载均衡器通信,而后端服务器不直接与客户端通信,因此称为 NAT 模式。

基于 DR 的 LVS 负载均衡

在 DR 模式下,LVS 负载均衡器仅负责将客户端请求转发给后端服务器,而不对请求的源地址和目标地址进行 NAT 转换。在这种模式下,负载均衡器和后端服务器必须在同一子网内,且后端服务器的响应包直接返回给客户端,不经过负载均衡器。为了实现这一点,负载均衡器和后端服务器之间通过 ARP 协议绑定了一个虚拟 IP 地址(VIP),客户端请求到达负载均衡器后,负载均衡器根据配置的转发规则,将请求直接转发给后端服务器,并通过 ARP 来告诉后端服务器响应的目标 MAC 地址,使得响应可以直接返回给客户端。

基于 TUN 的 LVS 负载均衡

在 TUN 模式下,LVS 负载均衡器将客户端请求转发给后端服务器,类似于 DR 模式,但后端服务器响应包返回给负载均衡器,而不是直接返回给客户端。后端服务器的响应经过负载均衡器后,再由负载均衡器转发给客户端。在 TUN 模式下,负载均衡器和后端服务器之间通过 IP 隧道建立连接,负载均衡器使用隧道 IP 地址与后端服务器通信,并将请求和响应进行封装和解封装以实现转发。

特性 LVS-TUN 模式 LVS-DR 模式
适用网络结构 后端服务器可以位于不同网络或地理位置 LVS 和后端服务器必须在同一局域网
数据包传输 使用 IP-in-IP 隧道封装数据包 直接修改 MAC 地址,保持 IP 地址不变
负载均衡器的负载 只处理入站请求,响应直接返回客户端 只处理入站请求,响应直接返回客户端
对后端服务器的要求 后端服务器必须支持 IP 隧道 后端服务器必须配置 loopback 上的 VIP
典型应用场景 分布式服务器集群,服务器在不同地理位置 局域网中的高性能服务器集群
封装开销 有 IP 隧道封装和解封装开销 没有额外封装开销

mock 服务中心架构

从图片可以看到,整体的服务架构很简单,我们使用一台机器作为负载均衡器,使用 lvs 的 DR 模式,将 72.50 作为虚拟 ip。当请求 72.50 的时候,会通过负载均衡算法,将请求转发到 72.49 及 72.51 两个服务上面。

以下为效果

未使用 LVS 负载均衡

未使用 LVS 负载均衡的情况下,压测机的流量使用达到 110M 左右。

使用 LVS 负载均衡后

由下图很明显可以看到,在采取 LVS 负载均衡后,压测机的网络流量由 110M 左右降低至 1M 以内,而两个 mock 服务均涨至 50M+,说明两台的负载均衡策略成功运行。
原因:改造之前,每个压测机内部会启动一个 mock 服务,当单机压测流量太高的时候,压测机器的网络带宽就会出现瓶颈。
现如今的改造是将 mock 服务拆分出来单独部署,使用 lvs 负载均衡分散流量,将流量分配到不同的节点上。
故从表现来看,压测机的流量降幅很高,是因为压测机器已经没有了 mock 服务。
我们只需要关注两台 mock 服务的流量分配即可。

压测机:72.36,
以下是发压节点的网络流量情况:

负载均衡器:10.13.72.48~10.13.72.50(50 为虚拟地址)

mock 服务:10.13.72.49

mock 服务:10.13.72.51

难点

  1. 被压服务只能配置一个 mock 服务的 url,无法配置多个 mock 服务的 url,在使用端没有做负载均衡。
  2. 流量吞吐量要求高,很容易达到宿主机的网卡瓶颈,需要分布式配置。
  3. 分布式配置不能采取反向代理或者流量都经过一个节点的模式。


↙↙↙阅读原文可查看相关链接,并与作者交流