☁️ 第五章 驱动云服务的技术
📄 一句话概括

负载均衡器做的事只有一句:把来的请求分给多台机器,并且保证分到的那台是活的。它看起来像【分发器】,真正的价值却在另一半——健康检查:坏掉的机器会被自动移出池子,等它好了再放回去。所以它分发的不只是流量,还是【可用性】。

📝 本节和前面几节的关系

上一节讲【网络在机房里怎么走】,这一节讲走到机房里之后,怎么决定交给哪一台。

它和 实现多云计算的容器 是一对:那一节讲的是副本怎么自动补(你声明 3 个,它就一直保持 3 个),这一节讲的是请求怎么自动挑(这么多副本,来一个请求交给谁)。一个管【有几台】,一个管【去哪台】。 它也接着 基本的系统架构——那一节说云没改【一问一答】这个结构,而这一节讲的正是这个结构里多出来的那一层。

一、它其实在做两件事

做什么 具体是什么 不做会怎样
分散 把请求按某种算法分给多台机器 一台忙死、其他闲死
挑活的 通过健康检查把坏机器移出池子 请求被送到已经死掉的机器上

第二件事比第一件重要得多。因为:

所以负载均衡器最核心的机制不是那几种算法,而是【健康检查 + 自动摘除】。 没有它,你只是把流量平均地分给了十台机器,其中有一台早就死了。

二、动手 Demo:四种算法与可用性账

看到什么算成功:

==================================================================================================
【Demo 4】负载的分散:网络负载均衡器
==================================================================================================
  负载均衡器做的事只有一句:把来的请求分给多台机器,
  并且保证【分到的那台是活的】。

  【一】四种分发算法,各适合什么

  算法            怎么分                    适合的场景
  ------------------------------------------------------------------------------------
  轮询            挨个轮着来                各台处理能力相近
  加权轮询        按能力比例分              机器配置不一样
  最少连接        给当前最闲的那台          请求耗时差别大
  一致性哈希      同一用户固定同一台        有会话、有缓存

  最常用的是【最少连接】而不是【轮询】:因为请求长短不一,
  轮询会把新请求继续压给正在忙的那台。

  【二】健康检查:什么时候把一台踢出去
    连续 3 次探测失败  → 从池子里移出
    恢复后连续 2 次成功 → 放回池子
  探测间隔决定【多久发现】。间隔 5 秒、连续 3 次 = 最长 15 秒后发现。
  间隔越短发现越快,代价是探测流量越多。

  【三】算一笔可用性的账(单台可用性按 99.0% 算)

  台数      整体可用性          一年停机              相当于
  ------------------------------------------------------------------------------
  1 台      99.0000%            87.6 小时             3.7 天
  2 台      99.9900%            52.6 分钟             一顿饭的工夫
  3 台      99.9999%            31.5 秒               感觉不到

  但这里有个前提:负载均衡器自己不能是单点。
  它一挂,后面十台全都不通——所以它自己也必须成对部署。

读结果:

三、两种层次:看 L4 还是看 L7

负载均衡器按【能看到多少信息】分成两类,这个区分决定了它能做多聪明的事:

层次 能看到什么 能做什么 代价
L4(传输层) IP 和端口 快,只做转发 看不见内容,做不了精细判断
L7(应用层) URL、Header、Cookie 按内容分发、终止加密 每请求开销更大

区别用一句话说清:L4 是【只看信封上的地址就分拣】,L7 是【拆开信看一眼内容再分拣】。

所以 L7 能做 L4 做不到的事:

而 L4 也不是没用:它开销小、延迟低、能扛的并发更高,对协议不敏感(不管你是 HTTP 还是别的什么)。所以现实里的架构常常是外层 L4 扛量、内层 L7 做精细路由——先用便宜的方式分流,再用聪明的方式细分。

30 秒实验

打开任意一家云服务商的负载均衡产品页,做两件事:

  1. 看它把负载均衡分成了几档(通常会有【网络型/四层】和【应用型/七层】两档),对比一下两档的价格。
  2. 找【健康检查】的配置项,看它默认的间隔和判定次数是多少。

做完这个你会看到一个规律:七层的那档通常更贵,因为每一层的智能都要付出算力的代价。而健康检查的参数(间隔几秒、失败几次才算失败)决定了你的系统在故障时【多久能恢复】——这个参数很少被人主动设置,但它对可用性的影响,比换一种分发算法大得多。

常见误区

  1. 错误:负载均衡就是把流量平均分给各台机器。——纠正:平均是目标之一,但不是最重要的那一半。真正让业务不出事故的是【健康检查 + 自动摘除】:没有它,流量会平均地分给十台机器,其中一台已经死了,那么大约十分之一的请求会失败。而有了健康检查,那一台会被移出池子,它的份额自动落到其他机器上。判断标准是:机器坏掉的那一刻,用户有没有感觉到——没感觉到,才叫负载均衡。

  2. 错误:有了负载均衡,服务就不会中断了。——纠正:它解决的是【一台机器坏了怎么办】,不解决【所有机器一起坏怎么办】。如果十台机器跑的是同一个有 bug 的版本,它们会一起挂;如果它们共用同一个数据库,数据库挂了照样全停。所以负载均衡只是可用性链条里的一环,它把单机故障的影响抹平了,但没有消除系统性故障——2-10 里讲的【备份不等于灾备】,是同一条道理的另一面。

  3. 错误:负载均衡器用了云服务商的托管服务,它就是不会挂的。——纠正:托管只是把【它自己也要做高可用】这件事交给了服务商,不是让它变得不会出故障。托管型负载均衡服务商确实会把它部署在多个可用区,但它的配置错、证书过期、后端全挂这些情况,托管服务一个也解决不了。所以真实系统里,前端(负载均衡)高可用 + 后端(服务实例)高可用 + 数据层高可用,三样都要有。

  4. 错误:探测间隔设得越短越好,这样发现故障快。——纠正:探测间隔是【发现速度】和【误判概率】之间的取舍。间隔太短,一次网络抖动就会被当成故障,机器被反复踢进踢出,业务反而更不稳定。所以正确的做法是两个参数一起看:间隔(多久探一次)+ 连续失败次数(几次才算真坏)。本节 Demo 里用的【间隔 5 秒、连续 3 次失败】,含义是最多 15 秒发现,但一次抖动不会误判。这个组合比【把间隔改到 1 秒】有用得多。

自测三问(点开对答案) 1. 为什么说健康检查比分发算法更重要? —— 因为**两者的失效后果不在一个量级**。分发算法不好,结果是**有的机器忙、有的闲**——这是效率问题;健康检查不做,结果是**请求被送到已经死掉的机器上**——这是可用性问题。**效率问题影响成本,可用性问题影响业务。** 而且有一个很现实的细节:**任何规模稍大的系统里,机器总有一些处于【半死不活】的状态**(进程在但响应超时、磁盘满了但还没报错)——**只有健康检查能发现这类问题**,靠人工巡检根本来不及。 2. 为什么带会话的业务要用【一致性哈希】而不是轮询? —— 因为**有些状态还留在机器本地**。最典型的是登录会话和本地缓存:如果同一个用户第二次请求被分到了另一台机器,**那台机器没有他的会话信息,就会表现为【刚登录完又要求登录】**。一致性哈希把【同一个用户】固定映射到【同一台机器】,绕开了这个问题。**但要注意:更好的做法其实是把会话状态外置**(放到共享的缓存里)——**这样就不需要固定映射,任何一台机器都能服务任何人**。这也是云原生架构普遍追求的方向。 3. 为什么负载均衡器自己会成为最关键的【单点】? —— 因为**它站在所有流量的必经之路上**。后端有十台机器,坏一台损失十分之一;**它只有一台,坏一台就是全部**。而且它的故障形式还特别隐蔽——**不是【不通】,而是【通但不转发】**,这时候后端所有机器都是健康的,监控上一切正常,**只有用户报错**。所以它的高可用要求比后端任何一台机器都高,典型做法是**至少两台 + 对外只有一个访问地址**。

相关笔记