【Ribbon】 实现原理

Metadata

title: 【Ribbon】 实现原理
date: 2023-01-09 17:28
tags:
  - 行动阶段/完成
  - 主题场景/组件
  - 笔记空间/KnowladgeSpace/ProgramSpace/ModuleSpace
  - 细化主题/Module/Ribbon/基础
categories:
  - Ribbon
keywords:
  - Ribbon
description: 【Ribbon】 实现原理

【Ribbon】 实现原理

我们使用RestTemplate对象只需要访问一个带有对象名称的路径,也就是http://userservice/user/XX,就可以访问到相对应的接口,这其中离不开LoadBalancerInterceptor的帮助,它会去RestTemplate的请求进行拦截,然后从Eureka中获取服务id与端口号,随后利用负载均衡算法得到真实的服务地址信息,替换服务id。

在LoadBalancerInterceptor这个类中,会有一个intercept方法,其拦截了用户的HttpRequest请求,通过调用以下api

  • request.getURI():获取请求uri,也就是 http://user-service/user/8
  • originalUri.getHost():获取uri路径的主机名,其实就是服务id,user-service
  • this.loadBalancer.execute():处理服务id,和用户请求。

获取到了url、主机名、和服务的id,再将这些信息作为参数传到LoadBalancerClient(this.loadBalancer)的execute的方法中

而在LoadBalancerClient的execute方法中可以通过服务id获取到服务列表,并获取合适的服务的端口号,其实现的主要api如下

  • getLoadBalancer(serviceId):根据服务id获取ILoadBalancer,而ILoadBalancer会拿着服务id去eureka中获取服务列表并保存起来。
  • getServer(loadBalancer):利用内置的负载均衡算法,从服务列表中选择一个。也就是127.0.0.1:8080

从这里可以知道,负载均衡的实现是在getServer方法中实现的

继续跟进

可以发现这里返回一个rule,那我们就再跟进看看这个rule到底是什么

可以发现,前面传过来的default对应的是RoundRobinRule对象

查询相关资料可以知道,RoundRobinRule对应的是一个轮询的规则,所以这里采用的默认负载均衡规则是轮询

Ribbon的主要流程

选择 负载均衡 策略

首先,先定义一个IRule

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

然后再yml文件进行配置

userservice:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则