链接: github https://github.com/Netflix/ribbon/wiki
知乎 https://zhuanlan.zhihu.com/p/28547575
spring社区 http://projects.spring.io/spring-cloud/spring-cloud.html#_spring_cloud_netflix
对HTTP和TCP客户端进行负载均衡控制
ribbon是客户端负载均衡,Feign默认使用了ribbon技术
同时zuul也使用ribbon做负载均衡
Ribbon的源码实现大致原理:
LoadBalancerClient : 继承了ServiceInstanceChooser接口,实现类是RibbonLoadBalancerClient.主要方法有choose(ServiceInstanceChooser用来选择instance) ,
execute(LoadBalancerClient 用来执行).
ILoadBalancer : 接口方法有addServers,chooseServer,markServerDown,getReachableServers,getAllServers. 用途同方法名
实现类为BaseLoadBalancer 和 DynamicServerListLoadBalancer.
BaseLoadBalancer : 主要由以下类进行配置 IClientConfig(基本配置,用于初始化) IRule(路由策略) IPing (判断响应) (静态配置负载均衡)
DynamicServerListLoadBalancer: ServerList(用于从Eureka中获取服务列表) ServerListFilter(列表过滤) (动态配置负载均衡)
负载均衡过程:
1.RibbonLoadBalancerClient接收到一个serviceid之后,调用ServiceInstanceChooser的choose方法,choose方法首先得到 ILoadBalancer (当中有client列表)。
再利用ILoadBalancer 的chooseServer方法得到普通Server实例并实例化RibbonServer,并返回。chooseserver会通过loadbalancer中的rule来返回正确的instance。
2. DynamicServerListLoadBalancer由iconfig初始化,初始化完成后调用updateListOfServers方法获得所有ServerList。(方法中通过ServerList实现类来访问EurekaClient中的注册列表)
3.BaseLoadBalancer中有一个PingTask任务,他每10秒钟会向EurekaClient发送一个Ping。如果从Eureka拉取的注册列表发生了改变,则重新更新列表。
4.LoadBalancerClient根据注册列表和IRule来进行负载均衡
@LoadBalanced注解的原理
被注解后,会维护一个restTemplate的列表。表中所有template都会被添加拦截器,拦截器会调用LoadBalancerClient接口的execute方法
springcloud中的应用
springcloud提供了默认的配置RibbonClientConfiguration。它提供了包含ILoadBalancer,ServerListFilter在内的许多配置。
你可以更改默认的配置,更改方法为在.property文件中添加
使用重写的配置java类,如:
@Configuration
@RibbonClient(name = "foo", configuration = FooConfiguration.class)
public class TestConfiguration {
}
这个client会同时使用默认的RibbonClientConfiguration和FooConfiguration配置,重复项后者会覆盖前者。重写的配置类最好放在一个其他的package中再引入,这样就不会被@ComponentScan自动扫描,被所有的@RibbonClient使用。
重写配置类:
@Configuration
public class FooConfiguration {
@Bean
public IPing ribbonPing(IClientConfig config) {
return new PingUrl();
}
}
同时使用Eureka和Ribbon,Eureka会将Ribbon中的众多接口重新实现以达到目的
如果没有使用Eureka,则需要添加配置项以激活RibbonClient的name属性,在application.yml中添加
stores: ribbon: listOfServers: example.com, google.com
直接使用Ribbon的Api
public class MyClass {
@Autowired
private LoadBalancerClient loadBalancer;
public void doStuff() {
ServiceInstance instance = loadBalancer.choose("stores");
URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
// ... do something with the URI
}
}
LoadBalancerClient会根据clientid得到正确的instance的URI,过程如开篇所讲
使用@RibbonClient和@LoadBalanced注解的实例 https://spring.io/guides/gs/client-side-load-balancing/