关于负载均衡器已经有很多文章,但今天要讨论的不是负载均衡器如何工作,而是如何防止负载均衡器成为单点故障。
负载均衡器是系统设计工具集中的绝佳工具,可帮助系统进行扩展。当我们需要为大流量提供服务时,将不可避免遇到单台服务器内存和计算能力不足以为所有流量提供服务的情况。此时,有以下两种选择:
- 通过增加处理能力和内存使服务器更强大,但有硬件上限约束。
- 也可以运行多个服务器实例,每个实例处理部分流量。
简单来说,负载均衡器会接收所有进入的流量,并智能的将流量分配给服务器的多个运行实例。这样只需要增加越来越多的服务器副本,就可以无限扩容。在系统设计术语中,这被称为水平扩容。
虽然负载均衡器可以在应用扩容时规避内存和计算限制,但并不能解决单点故障问题。
从上图可以看到,所有请求都要经过负载均衡器,然后由负载均衡器将请求转发到后端副本。很明显,在这种情况下,负载均衡器本身就是一个单点。如果负载均衡器关闭或由于某种原因无法访问,用户将无法使用应用程序,从而造成业务全面中断。
那么该如何防止出现这种情况,如何防止负载均衡器造成单点故障呢?下面我们将讨论如何解决这一问题。
部署高可用主从负载均衡器
解决这个问题的一个办法是将负载均衡器部署为高可用对,这意味着要部署两个或更多负载均衡器实例,一旦其中某个负载均衡器出现故障,其他负载均衡器就能接替并继续为客户提供服务。
听起来似乎是个合理的解决方案,但马上想到的第一个问题是,客户如何知道需要向哪个负载均衡器实例发出请求?如果负载均衡器的某个实例出现故障,其他负载均衡器如何知道?
我们来解决这些问题。
如何管理本地网络流量
要回答上述问题,必须了解以下有关网络路由的要点,我们需要深入了解流量是如何在网络中路由的。
- 本地网络内的所有流量都由一台名为"交换机"的设备管理,而不是路由器。
- 交换机通过主机 MAC 地址向它们发送流量。
- 每当交换机收到带有目标 IP 地址的 TCP 数据包时,都需要知道相应主机的 MAC 地址,以便将 TCP 数据包正确转发给正确的目标机器。
- 为了解析目标 IP 地址的 MAC 地址,交换机将使用地址解析协议 (ARP,Address Resolution Protocol),向连接到本地网络的所有机器发送广播,询问它们是否正在为给定的 IP 提供服务。
- 拥有给定 IP 的主机将回复其 MAC 地址,而其他主机将直接忽略 ARP 请求。
了解了网络路由的工作原理后,让我们回到最初的问题。
第一步是在网络中部署两个负载均衡器,其中一个为主模式,另一个为从模式,这种主从模式在高可用性系统中非常常见。
这两个负载均衡器同意共享同一个虚拟 IP 地址(虚拟 IP 地址分配给软件系统,如负载均衡器,而不是物理设备,因此可以将其视为一个虚构的 IP 地址),并且互相发送心跳(liveness ping)。
每当交换机要将数据包转发到虚拟 IP 地址时,首先向网络上的所有主机发送广播,询问哪些机器的 MAC 地址分配了虚拟 IP 地址。主负载均衡收到广播后,会立即以其 MAC 地址作出回应,这样交换机就知道,今后所有属于虚拟 IP 地址的数据包都应转发给主负载均衡器。从负载均衡器也会收到该广播,但不会用自己的 MAC 地址做出回应,因为它知道自己不是主负载均衡器。
两个负载均衡器不断相互发送心跳(liveness ping)信息。如果主负载均衡器发生故障,从负载均衡器会立即开始为虚拟 IP 地址公布自己的 MAC 地址,从而承担起主负载均衡器的角色。
将 IP 地址解析为 MAC 地址的整个过程是通过地址解析协议(简称 ARP)完成的。
请注意,使用 ARP 将 MAC 地址解析为 IP 地址的过程相当快,因此当主负载均衡器发生故障时,终端用户可能不会看到明显的停机时间。
这就是我们确保负载均衡器不会成为单点故障的方法。请注意,还可以使用其他策略来解决这个问题,例如使用多播,或监控负载均衡器并自动更新 DNS 以指向健康的负载均衡器等。