学习笔记-架构的演进之负载均衡-2月day21

前言

服务发现、网关路由、负载均衡和调用容错,都带有“从服务集群中寻找到一个合适的服务来调用”的含义。它们之前存在差别,也存在业务实现上的重合。(实例可参考附录连接)

一个从广州机房内网发出的服务请求,绕到了网络边缘的网关、负载均衡器这些设施上,然后再被分配回内网中另外一个服务去响应。这不仅消耗了带宽,降低了性能,也增加了链路上的风险和运维的复杂度。可是,如果流量不经过这些设施,它们相应的职责就无法发挥作用了:如果不经过负载均衡器的话,甚至连请求应该具体交给哪一个服务去处理都无法确定。

如何简化这个调用过程?让我们讨论负载均衡器的实现。

客户端负载均衡器

对于任何一个大型系统来说,负载均衡器都是必不可少的设施。
集中式负载均衡是经典的部署形式,只部署在整个服务集群的前端,再将用户的请求分流到各个服务进行处理。

微服务的日渐流行,服务集群收到的请求来源不再局限于外部,越来越多的访问请求是由集群内部的某个服务发起,由集群内部的另一个服务进行响应的。针对内部流量的特点,直接在服务集群内部消化掉,肯定是更合理、更受开发者青睐的办法。

客户端负载均衡器(Client-Side Load Balancer)是一种独立位于每个服务前端的、分散式的负载均衡方式。相比较下,集中式负载均衡又被称为服务端负载均衡器(Server-Side Load Balancer)。
在这里插入图片描述

服务端负载均衡器是集中式的,同时为多个节点提供服务,而客户端负载均衡器是和服务实例一一对应的,而且与服务实例并存于同一个进程之内。优点是:

  1. 均衡器与服务之间的信息交换是进程内的方法调用,不存在任何额外的网络开销。
  2. 客户端均衡器不依赖集群边缘的设施,所有内部流量都仅在服务集群的内部循环,避免出现前面提到的,集群内部流量要“绕场一周”的尴尬局面。
  3. 分散式的均衡器意味着它天然避免了集中式的单点问题,它的带宽资源将不会像集中式均衡器那样敏感,这在以七层均衡器为绝对主流、不能通过 IP 隧道和三角传输这样的方式来节省带宽的微服务环境中,显得更具优势。
  4. 客户端均衡器要更加灵活,能够针对每一个服务实例单独设置均衡策略等参数。比如访问某个服务是否需要具备亲和性,选择服务的策略是随机、轮询、加权还是最小连接,等等,都可以单独设置而不影响其他服务。

当然也存在不足:

  1. 与服务运行于同一个进程之内,就意味着它的选型要受到服务所使用的编程语言的限制。因为要为每种语言都实现对应的能够支持复杂网络情况的均衡器是非常难的。这个缺陷其实有违于微服务中,技术异构不应受到限制的原则。、
  2. 从个体服务来看,由于客户端均衡器与服务实例是共用一个进程,均衡器的稳定性会直接影响整个服务进程的稳定性,而消耗的 CPU、内存等资源也同样会影响到服务的可用资源。从集群整体来看,在服务数量达到成千乃至上万的规模时,客户端均衡器消耗的资源总量是相当可观的。
  3. 由于请求的来源可能是来自集群中任意一个服务节点,而不再是统一来自集中式均衡器,这就会导致内部网络安全和信任关系变得复杂,当入侵者攻破任何一个服务时,都会更容易通过该服务突破集群中的其他部分。
  4. 服务集群的拓扑关系是动态的,每一个客户端均衡器必须持续跟踪其他服务的健康状况,以实现上线新服务、下线旧服务、自动剔除失败的服务、自动重连恢复的服务等均衡器必须具备的功能。由于这些操作都需要通过访问服务注册中心来完成,因此数量庞大的客户端均衡器需要一直持续轮询服务注册中心,这也会为它带来不小的负担。

代理客户端负载均衡器

服务网格(Service Mesh)的盛行,产生了“代理客户端负载均衡器”(Proxy Client-Side Load Balancer)的客户端均衡器变体形式,它解决了此前客户端均衡器的大部分缺陷,将原本嵌入在服务进程中的均衡器提取出来,放到边车代理中去实现。
在这里插入图片描述

虽然代理均衡器与服务实例不再是进程内通讯,而是通过虚拟化网络进行数据交换的,数据要经过操作系统的协议栈,要进行打包拆包、计算校验和、维护序列号等网络数据的收发等步骤(Envoy 中支持使用Unix Domain Socket来进一步避免这种消耗),流量比起之前的客户端均衡器确实多经历了一次代理过程。
不过,Kubernetes 严格保证了同一个 Pod 中的容器不会跨越不同的节点,相同 Pod 中的容器共享同一个网络和Linux UTS 名称空间,因此代理均衡器与服务实例的交互,仍然要比真正的网络交互高效且稳定得多,代价很小。其收益在于:

  1. 代理均衡器不再受编程语言的限制。比如说,要发展一个支持 Java、Golang、Python 等所有微服务应用的通用代理均衡器,就具有很高的性价比。集中不同编程语言的使用者的力量,也更容易打造出能面对复杂网络情况的、高效健壮的均衡器。即使退一步说,独立于服务进程的均衡器,也不会因为自身的稳定性而影响到服务进程的稳定。
  2. 在服务拓扑感知方面,代理均衡器也要更有优势。由于边车代理接受控制平面的统一管理,当服务节点拓扑关系发生变化时,控制平面就会主动向边车代理发送更新服务清单的控制指令,这避免了此前客户端均衡器必须长期主动轮询服务注册中心所造成的浪费。
  3. 在安全性、可观测性上,由于边车代理都是一致的实现,有利于在服务间建立双向 TLS 通讯,也有利于对整个调用链路给出更详细的统计信息。

地域与区域涉及到的负载均衡

  1. region
    Region是地域的意思,比如华北、东北、华东、华南,这些都是地域范围。面向全球或全国的大型系统的服务集群,往往都会部署在多个不同的地域,不同的地域之间是没有内网连接的,所有流量都只能经过公众互联网相连,如果微服务的流量跨越了地域,实际上就跟调用外部服务商提供的互联网服务没有任何差别了。所以,集群内部流量是不会跨地域的,服务发现、负载均衡器也默认是不会支持跨地域的服务发现和负载均衡
  2. zone
    Zone 是区域的意思,它是可用区域(Availability Zones)的简称。区域的意思是在地理上位于同一地域内,但电力和网络是互相独立的物理区域,比如在华东的上海、杭州、苏州的不同机房,就是同一个地域的几个可用区域。同一个地域的区域之间具有内网连接,流量不占用公网带宽,因此区域是微服务集群内,流量能够触及的最大范围。 (应用是只部署在同一区域内,还是部署到几个可用区域中,主要取决于你是否有做异地双活的需求,以及对网络延时的容忍程度。)
  • 如果你追求高可用,比如希望系统即使在某个地区发生电力或者骨干网络中断时,仍然可用,那你可以考虑将系统部署在多个区域中。这里你要注意异地容灾和异地双活的差别:容灾是非实时的同步,而双活是实时或者准实时的,跨地域或者跨区域做容灾都可以,但一般只能跨区域做双活,当然你也可以将它们结合起来同时使用,即“两地三中心”模式。
  • 如果你追求低延迟,比如对时间有高要求的SLA 应用,或者网络游戏服务器等,那就应该考虑将系统部署在同一个区域中。因为尽管内网连接不受限于公网带宽,但毕竟机房之间的专线容量也是有限的,难以跟机房内部的交换机相比,延时也会受物理距离、网络跃点等因素的影响。

当然,可用区域对应于城市级别的区域范围,在一些场景中仍然是过大了一些,即使是同一个区域中的机房,也可能存在不同的具有差异的子网络,所以部分的微服务框架也提供了 Group、Sub-zone 等做进一步的细分控制。这些参数的意思通常是加权或优先访问同一个子区域的服务,但如果子区域中没有合适的,还是会访问到可用区域中的其他服务。

此文章为2月Day21学习笔记,内容来源于极客时间《周志明的软件架构课

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值