【微服务】2、一篇文章详解 Ribbon 负载均衡

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 【微服务】2、一篇文章详解 Ribbon 负载均衡


一、负载均衡原理(debug 源码)

(1) 基本介绍

📖 @LoadBalanced 注解表示:将来 RestTemplate 发起的请求要被 ribbon 拦截

📖 这个拦截操作是通过 LoadBalancerInterceptor 完成的

📖 它是 SpringCloud 中的拦截器org.springframework.cloud.client.loadbalancer

📖 LoadBalancerInterceptorClientHttpRequestInterceptor 接口的实现类



(2) 打断点

① LoadBalancerInterceptor.java - intercept()

public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
    final ClientHttpRequestExecution execution) throws IOException {
  // 获取请求地址
  final URI originalUri = request.getURI();
  // 获取主机名(微服务的服务名)
  String serviceName = originalUri.getHost();
  // 判断服务名是否为空
  Assert.state(serviceName != null,
      "Request URI does not contain a valid hostname: " + originalUri);
  // this.loadBalancer: RibbonLoadBalancerClient
  // 进入 this.loadBalancer.execute 方法
  return this.loadBalancer.execute(serviceName,
      this.requestFactory.createRequest(request, body, execution));
}

② RibbonLoadBalancerClient.java - execute()

public <T> T execute(String serviceId, LoadBalancerRequest<T> request)
    throws IOException {
  // serviceId: 服务名
  return execute(serviceId, request, null);
}

③ RibbonLoadBalancerClient.java - execute()

🔋 调用 RibbonLoadBalancerClient 重载的另一个 execute() 方法

public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
    throws IOException {
  // 通过服务名获取负载均衡器
  // loadBalancer 的 allServerList 中包含服务地址信息
  ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
  // 负载均衡, 获取某个服务地址信息
  Server server = getServer(loadBalancer, hint);
  if (server == null) {
    throw new IllegalStateException("No instances available for " + serviceId);
  }
  RibbonServer ribbonServer = new RibbonServer(serviceId, server,
      isSecure(server, serviceId),
      serverIntrospector(serviceId).getMetadata(server));
  return execute(serviceId, ribbonServer, request);
}

④ RibbonLoadBalancerClient.java - getServer()

protected Server getServer(ILoadBalancer loadBalancer, Object hint) {
  if (loadBalancer == null) {
    return null;
  }
  // Use 'default' on a null hint, or just pass it on?
  return loadBalancer.chooseServer(hint != null ? hint : "default");
}

⑤ ZoneAwareLoadBalancer.java - chooseServer()

🔋 调用父类的 chooseServer()

⑥ BaseLoadBalancer.java - chooseServer()

public Server chooseServer(Object key) {
    if (counter == null) {
        counter = createCounter();
    }
    counter.increment();
    // rule 默认是 ZoneAvoidanceRule 类型, 不为 null
    if (rule == null) {
        return null;
    } else {
        try {
            // 根据 key 选择一个活着的的服务
            return rule.choose(key);
        } catch (Exception e) {
            logger.warn("LoadBalancer [{}]:  Error choosing server for key {}", name, key, e);
            return null;
        }
    }
}

⑦ RibbonLoadBalancerClient.java - execute()

🔋 拿真实的服务地址替换服务名

(3) 流程

二、负载均衡策略

(1) 负载均衡策略

📝 Ribbon 的负载均衡策略是通过一个叫做 IRule 的接口来定义的,每个实现类是一种策略

(2) 调整负载均衡策略

📝 有种方式指定 IRule 实现,进而修改负载均衡规则

① 注入(@Bean)自己需要的负载均衡策略(IRule)

全局:整个微服务

@Bean
  public IRule iRule() {
      return new RandomRule();
  }

📝 整个微服务发送的请求都通过【随机】方式负载均衡

② yaml 文件指定对某个指定微服务发送请求的使用采用指定的负载均衡策略

局部:只对某个微服务有作用

userservice: # 该微服务向 userservice 发送的请求使用【随机】负载均衡
  ribbon:
   NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

(3) 饥饿加载

📝 Ribbon 默认是采用懒加载 【第一次访问时才会创建 LoadBalanceClient,请求时间会很长】

📝 饥饿加载会让 LoadBalanceClient 在项目启动时被创建,进而降低第一次访问的耗时

ribbon:
  eager-load:
    enabled: true # 开启饥饿加载
    clients:
      - userservice # 指定对哪些微服务进行饥饿加载

📖 根据 Bilibili 黑马程序员进行学习

📖 如有错误,请不吝赐教哦

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
2月前
|
负载均衡 算法 架构师
Ribbon负载均衡
上一节就已经实现的负载均衡笔者并未深入探讨,本节通过分析负载均衡算法、Ribbon实现负载均衡的底层原理和实现过程,让大家对负载均衡有了一个大体认识,同时针对Ribbon自定义负载均衡策略,饥饿加载让大家对于Ribbon的了解又多一些。Ribbon实现的负载均衡只是方案之一,我们可以尽量多了解但不要局限于此。
|
20天前
|
负载均衡 Java Nacos
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
|
5天前
|
负载均衡 Java 开发者
Ribbon框架实现客户端负载均衡的方法与技巧
Ribbon框架为微服务架构中的客户端负载均衡提供了强大的支持。通过简单的配置和集成,开发者可以轻松地在应用中实现服务的发现、选择和负载均衡。适当地使用Ribbon,配合其他Spring Cloud组件,可以有效提升微服务架构的可用性和性能。
7 0
|
2月前
|
存储 设计模式 缓存
OpenFeign集成Ribbon负载均衡-过滤和选择服务核心实现
该文章主要介绍了如何在OpenFeign中集成Ribbon以实现负载均衡,并详细分析了Ribbon中服务选择和服务过滤的核心实现过程。文章还涉及了Ribbon中负载均衡器(ILoadBalancer)和负载均衡策略(IRule)的初始化方式。
OpenFeign集成Ribbon负载均衡-过滤和选择服务核心实现
|
2月前
|
缓存 负载均衡 Java
OpenFeign最核心组件LoadBalancerFeignClient详解(集成Ribbon负载均衡能力)
文章标题为“OpenFeign的Ribbon负载均衡详解”,是继OpenFeign十大可扩展组件讨论之后,深入探讨了Ribbon如何为OpenFeign提供负载均衡能力的详解。
OpenFeign最核心组件LoadBalancerFeignClient详解(集成Ribbon负载均衡能力)
|
3月前
|
负载均衡 算法 网络协议
Ribbon 负载均衡源码解读
Ribbon 负载均衡源码解读
52 15
Ribbon 负载均衡源码解读
|
3月前
|
负载均衡 Java API
Feign 进行rpc 调用时使用ribbon负载均衡源码解析
Feign 进行rpc 调用时使用ribbon负载均衡源码解析
64 11
|
3月前
|
负载均衡 监控 Kubernetes
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
|
3月前
|
缓存 负载均衡 算法
微服务之客户端负载均衡
微服务中的客户端负载均衡是指将负载(即工作任务或访问请求)在客户端进行分配,以决定由哪个服务实例来处理这些请求。这种负载均衡方式与服务端负载均衡相对,后者是在服务端(如服务器或负载均衡器)进行请求的分发。
54 5
|
4月前
|
缓存 负载均衡 NoSQL
Redis系列学习文章分享---第十四篇(Redis多级缓存--封装Http请求+向tomcat发送http请求+根据商品id对tomcat集群负载均衡)
Redis系列学习文章分享---第十四篇(Redis多级缓存--封装Http请求+向tomcat发送http请求+根据商品id对tomcat集群负载均衡)
68 1
下一篇
无影云桌面