WEB 负载均衡

Posted by Oscaner on December 12, 2018

前言

日常业务中, 有些时候进行性能扩展是显而易见的, 比如下载服务由于带宽不足而必须进行扩展。

但是, 另一些时候, 很多人一看到站点性能不尽人意, 就马上实施负载均衡等扩展手段, 真的需要这样做吗?

当然, 这个问题也只有他们自己能回答, 除了出于高可用性和就近部署的考虑, 大多数情况下这种行为都显得有些为时尚早。

那么, 是不是一开始就安全不必考虑规模扩展呢?

答案恰恰相反, 作为一名架构师, 从一开始就要思考未来的扩展计划, 并且为扩展而进行架构设计。

但是关键在于, 你必须能够意识到何时需要实施扩展, 并且有足够的数据来证明这种必要性。

值得一提的是, 服务器自身硬件的垂直扩展不在我们的讨论之中, 我们所谈及的扩展, 主要指的是水平扩展。

我们经常用可扩展性来反映这种扩展能力,

所谓扩展性, 实际上是指系统通过扩展规模来提升承载能力的本领, 这种本领往往体现在增加物理服务器或者集群节点等方面。

可以说, 这种本来越强, 承载能力可提升的空间就越大。

但是, 这种本来总是受到或多或少的制约, 比如, 我们之所以不讨论单机垂直扩展, 就是因为单机的扩展能力非常有限, 很快就会遇到技术制约, 并且随着规模的增大而越来越昂贵。

的确, 即使最强大的单机也无法满足我们的需要

一些思考

对于 WEB 站点的水平扩展, 负载均衡是一种常见的手段。

在介绍负载均衡的多种实现方法之前, 我们先来思考一些问题。

假如某公司有一个小型团队, 需要承担一定的工作量。

开始的时候, 大家各尽其能, 非常轻松地就可以完成工作, 不亦乐乎。

但是, 随着公司的发展, 这个团队的工作量逐渐增大, 超出了团队成员的承受能力, 工作完成质量开始下降。

于是就有了接下来 。。。

外包

出于一些考虑, 这个团队决定将一部分工作任务外包给其他公司来做, 以减轻自己的负担, 同时由团队中的一个人负责与外包公司进行长期沟通, 这里我们称他为外包接口人。

显然, 外包使得团队承载能力的扩展成为可能, 而且随着工作任务的继续增加, 一家外包公司无法应付, 这个团队又找到了更多的外包公司同时进行合作, 外包接口人负责与这些公司分别进行沟通。

这样一来, 公司只需要花费一个人力和一些费用, 就可以完成大量持续增加的工作

然而。。。

接口人

突然有一天, 外包接口人由于病假没能来公司上班。

这下公司着急了, 因为与外包公司的沟通工作需要时刻进行, 而只有这名外包接口人熟悉这个工作,

这使得原本有序的外包工作不得不受到严重影响, 多家外包公司暂时停了下来,

直到第二天, 这位外包接口人回到公司后, 外包工作才恢复正常。

显然, 这位外包接口人非常关键, 他的缺席将会影响整个外包工作的正常进行,

也许这是致命的, 我们将这种情况称之为 单点故障 (Single Point of Failure),

如果公司只依赖一个因素、系统、设备或人, 就会暴露出单点故障的隐患。

所以, 为了避免单点故障, 公司为这位外包接口人配备了一名助理, 全力协助他的工作,

并且当他偶尔不在公司的时候, 助理可以很好地充当他的角色继续工作。

工作量分配

刚才说到, 外包接口人需要跟多个外包公司进行沟通, 并且将工作任务持续不断地分配给他们。

那么, 在任务分配过程中, 可能会发生这样一些情况:

  • 给有些外包公司分配了太多的任务, 其中一些任务没能按时完成
  • 有些外包公司比较闲, 可是却没能及时给他们分配任务
  • 有些外包公司业务能力差, 却给他们分配了高难度的任务, 花费了大量的时间, 最后还可能无法完成
  • 有些外包公司业务能力强, 却给他们分配了非常简单的任务, 支出了不必要的高额外包费用

如此一来, 我们看到一个最优化任务分配的问题。

当然, 这个问题是需要外包接口人来考虑的。

同时, 他需要借助一些过程管理方法来掌握各外包公司的进度和状态, 了解各外包公司的“负载”, 以帮助自己更加有效地分配任务, 实现外包工作的 负载均衡 (Load Balancing)

风险管理

尽管我们已经在一定程度上避免了外包接口人的单点故障, 降低了风险, 但是外包公司方面仍然有可能出现问题。

在必要的时候, 我们需要采取行动, 将任务快速转移给其他的外包公司, 前提是有足够的备用外包公司可以选择。

从避免单点故障到准备备用方案, 都是降低外包工作风险的一系列措施。

同时也保障了外包工作的不间断运转, 或者称之为 高可用性 (High Availability)

制约

当更多的工作任务需要外包时, 这位接口人的工作有点吃不消了, 因为:

  • 一个接口人负责大量的任务, 与多家外包公司分别进行沟通, 这几乎花费了他全部的工作时间
  • 一个接口人管理多家外包公司, 已经超出了他的管理能力

显然, 这些原因也是制约接口人处理更多外包工作的因素, 这些因素限制了外包工作的无限扩展。

这时, 公司决定设立更多的外包接口人, 成立一个新的团队, 其中每位外包接口人分别负责管理一部分外包公司, 并跟进相关的外包工作。

最终的外包工作关系图如图所示:

1.png

总结

在以上假想的外包工作场景中, 我们遇到了一系列的问题, 并提出了解决方案, 这些问题在 WEB 站点扩展的过程中同样存在。

接下来我们将回到 WEB 站点扩展的主题中, 探讨如何实现可扩展的 WEB 负载均衡系统。

当然, 除了我们关注的性能之外, 高可用性也会有所涉及。

常用负载均衡

HTTP 重定向

对于 HTTP 重定向, 你一定不陌生, 它可以将 HTTP 请求进行转移。

在 WEB 开发中, 我们经常会用它来完成自动跳转, 比如用户登录成功后跳转到相应的管理页面。

这种重定向完全由 HTTP 定义, 并且由 HTTP 代理和 WEB 服务器共同实现。

很简单, 当 HTTP 代理 (比如浏览器) 向 WEB 服务器请求某个 URL 后, WEB 服务器可以通过 HTTP 响应头信息中的 LOCATION 标记来返回一个新的 URL, 这意味着 HTTP 代理需要继续请求这个新的 URL, 这便完成了自动跳转。

当然, 如果你自己写了一个 HTTP 代理, 也可以不支持重定向, 也就是对于 WEB 服务器返回的 LOCATION 标记视而不见, 虽然这可能不符合 HTTP 标准, 但这完全取决于你的应用需要。

也正是因为 HTTP 重定向具备了请求转移和自动跳转的本领, 除了满足应用程序需要的各种自动跳转之外, 它还可以用于实现负载均衡, 以达到 WEB 扩展的目的。

DNS 负载均衡

我们知道, DNS 负责提供域名解析服务。

当我们访问某个站点时, 实际上首先需要通过该站点域名的 DNS 服务器来获取域名指向的 IP 地址。

在这一过程中, DNS 服务器完成了域名到 IP 地址的映射。

同样, 这种映射也可以是一对多的。这时候, DNS 服务器便充当了负载均衡调度器 (也称均衡器) , 它就像前面提到的重定向转移策略一样, 将用户的请求分散到多台服务器上, 但是它的实现机制完全不同。

反向代理负载均衡

反向代理服务器的核心工作便是转发 HTTP 请求, 因此它工作在 HTTP 层面, 也就是 TCP 七层结构中的应用层 (第七层) , 因而基于反向代理的负载均衡也称为七层负载均衡。

实现它并不困难, 目前几乎主流的 WEB 服务器都热衷于支持基于反向代理的负载均衡。

IP 负载均衡

事实上, 在数据链路层 (第二层) 、网络层 (第三层) 以及传输层 (第四层) 都可以实现不同机制的负载均衡。

但有所不同的是, 这些负载均衡调度器的工作必须由 Linux 内核来完成。

因为我们希望网络数据包在从内核缓冲区进入进程用户地址空间之前, 尽早地被转发到其他实际服务器上。

没错, Linux 内核当然可以办得到, 位于内核的 Netfilter 和 IPVS 可以解决问题, 而用户空间的应用程序对此却束手无策。

另一方面, 也正是因为可以将调度器工作在应用层以下, 这些负载均衡系统可以支持更多的网络服务协议, 比如 FTP、SMTP、DNS, 以及流媒体和 VOIP 等应用


本文由 Oscaner 创作, 采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外, 均为本站原创或翻译, 转载前请务必署名