客户端负载均衡器

以前,负载均衡器大多只部署在整个服务集群的前端,将用户的请求分流到各个服务进行处理,这种经典的部署形式现在被称为集中式的负载均衡

随着微服务日渐流行,服务集群的收到的请求来源不再局限于外部,越来越多的访问请求是由集群内部的某个服务发起,由集群内部的另一个服务进行响应的,针对内部流量的特点,直接在服务集群内部消化掉,肯定是更加优秀的方案,这就是服务内部负载均衡

等于之前的负载均衡是一种集中的转发模式,是配置在服务器前面的装置,现在的客户端负载均衡是在微服务的架构中,服务主动去配置的一个装置,它负载该服务实例去请求别的实例时的负载均衡,客户端均衡器是和服务实例一一对应的,每个服务实例都有一个自己专属的客户端均衡器,而且与服务实例并存于同一个进程之内,它不是集中式的,是分布式的,是配置在所有实例上的一个额外的小装置,客户端负载均衡器能将请求合理分配到不同的微服务实例上,保障各个微服务的负载处于合理水平

优点:

  • 均衡器和实例之间处于同一个进程,没有网络开销
  • 不依赖任何外部的设置,均存在于同一个集群下的内部流量
  • 分散的方式避免了单点故障
  • 灵活性非常高,每一个服务实例都可以配置不同的专属自己的负载均衡策略,比如:轮询、随机、权重、最小连接数等

缺点:

  • 它与服务运行于同一个进程之内,所以要跟服务有着同样的编程语言,不然怎么叫同一个进程呢,对吧
  • 布置过多的负载均衡器,会增加系统资源的消耗,比如:内存、CPU 等
  • 由于请求的来源可能是来自集群中任意一个服务节点,而不再是统一来自集中式均衡器,这就使得内部网络安全和信任关系变得复杂
  • 服务集群的拓扑关系是动态的,每一个客户端均衡器必须持续跟踪其他服务的健康状况

改进版客户端负载均衡器 --- 代理客户端负载均衡器

服务网格 (Service Mesh) 开始逐渐盛行后,代理客户端负载均衡器来了,将原本嵌入在服务进程中的均衡器提取出来,作为一个进程之外,同一 Pod 之内的特殊服务,放到边车代理 (sidecar) 中去实现,所以你可以理解为,当你使用了服务网格,并且配置了一个 sidecar 机制之后,这个 sidecar 就变成了代理客户端负载均衡器,从原本的同进程,改成了不同进程,只是同一个 Pod 的关系。这样之后,你完全用 Java 写的 sidecar 代理负载均衡器部署在 go 写的进程,同处一个 Pod 之中。

Kubernetes 严格保证了同一个 Pod 中的容器不会跨越不同的节点,这些容器共享着同一个网络名称空间,因此代理均衡器与服务实例的交互,实质上是对本机回环设备的访问,仍然要比真正的网络交互高效且稳定得多

服务网格配合 k8s 来使用也是近来成熟的搭配方案。