水平拓展的决策是我们创业路上一个重要的转折点。我们将从单服务器转向集群模式。但是如果没有能有效调动军队的指挥官和指令系统,那再大的集群也没用。我们现在已经拥有了随时可以开工的一群厨师,还需要一个懂得如何为厨师分配顾客点单的首席服务员。
在技术场景中,这位首席服务员,亦或可作为交警的角色,是由负载均衡扮演的,它是整个体系至关重要的一环。
深入技术细节:负载均衡是什么?
其实就按字面意思理解就行了。负载均衡就是前置于应用服务器集群的一组服务,它的唯一工作就是在应用服务器之间均衡地分配请求流量,不会让某个应用服务器承担太多。
对于外部用户来说,负载均衡服务就是要访问的网站本身。所有用户都访问同一个指向负载均衡服务的域名(比如我们的dukaan.app)。用户完全不知道在那个域名背后可能是一个拥有着2台或是10台甚至是100台服务器的集群正在准备处理请求提供响应。负载均衡就像一扇大门,把厨房里的复杂忙碌都遮挡了起来。
更好的类比是,负载均衡服务就像繁忙超市里的当班经理。
设想顾客已经排起了长龙(网络流量)等待付款。如果结账柜台只有一个工作人员,那排队的人很快就会越来越多。顾客会因为等待变得越来越焦躁,结账的工作人员也会焦头烂额。
现在超市经理决定再新开四个结账柜台(类似我们的应用服务器集群)。但顾客不是随机挑一个柜台去结账,我们聪明的经理会站在柜台前,积极地引导队伍里下一个顾客去到当前空闲的结账柜台:
- “您好先生,请到3号柜台结账。”
- “您好女士,柜台1现在空出来了,您可以到那边结账。”
可以看出来,这位经理就扮演了类似负载均衡的角色。他们的工作都是确保每一个结账柜台的工作人员不会超负荷,也不会有人因为没有顾客前去结账而无所事事。他们为客流削峰填谷,保证系统高效运行。负载均衡同时也负责健康检查。如果某个工作人员突然晕倒(类似服务器宕机),经理会立刻停止给他再安排结账顾客,而是会把顾客引导去其他正常工作的柜台。这样系统就能保持稳定的运行。
深入技术细节:负载均衡算法
超市经理需要一套规则(或者说某种策略)来决定下一位顾客前往的结账柜台。在负载均衡的世界,这些规则被称为算法。有的算法可能非常复杂,我们这里只需要搞明白两种最常见的类型:
- 轮询(Round Robin)分配:简单而蠢萌的方法
这是最基本的负载均衡算法。也很容易按字面理解:简单的循环分配请求给所有的服务器。
- 第1个请求分配给服务器A。
- 第2个请求分配给服务器B。
- 第3个请求分配给服务器C。
- 第4个请求再次分配给服务器A。
- 。。。以此类推。
就像给一群玩家发扑克牌。每位玩家都会轮流得到一张牌。
- 优点:超级简单,基本无需负载均衡服务额外思考。
- 缺点(蠢萌的部分):轮询假设每一个请求都大差不差,每一个服务器也都有类似的配置。但如果发送到服务器B的第2个请求是耗时10秒的复杂任务,而其它请求都是耗时1秒的简单任务呢?轮询可不管这些。即使此时服务器B仍然正在为之前那个复杂的任务忙碌,它仍会继续把第4个和第5个请求发给服务器B,而全然不顾服务器A此时可能完全无活可干。这会导致服务器之间工作负荷的分配不均。
- 最少连接(Least Connections)分配:更聪明的方法
这是一种更聪明的动态算法。负载均衡服务会实时监控集群中每一个应用服务器当前有效连接的数量。当新的网络请求到达时,负载均衡服务会把它送到当前连接数量最少的服务器。
这就像超市经理学聪明了,不是简单地按照编号告诉顾客该去哪个柜台结账,而是会根据排队人数多少给顾客挑一个人数最少的柜台。
- 优点:这种方法天然考虑到了有些请求会处理得比其它请求慢一些的情况。如果某台服务器正忙着处理复杂的请求,它会同时维持更多的用户连接,所以负载均衡会暂时不考虑继续给它新增任务,以便它尽快完成手头的活。这让工作负荷的分配更加公平也更有效率。
- 缺点:负载均衡的工作会稍微复杂一些,因为它现在不只是傻傻地按照服务器列表做轮询,而是需要时刻关注每个服务器的连接数量。
对于Dukaan网站来说,我们的选择已然明了。“最少连接”算法是更聪明更健壮的办法,能够更好地应对我们不可预知的用户流量。
现在理论部分已经清楚了。我们的网络交警有了一整套分配规则。是时候付诸实际了。我们需要一个合适的负载均衡工具并用它来管理我们全新的服务器集群。