spring cloud ribbon和Feign的实现原理分析及自定义实现

1 RestTemplate
使用:restTemplate.getForObject(“http://serviceName/uri?queryStr”);
首先:
Robbin的负载策略就是基于RestTemplate实现的
InterceptingHttpAccessor有个属性List interceptors
请求拦截器
RestTemplate
LoadBalancerInterceptor 这里有个属性:LoadBalancerClient loadBalancer;
当加入了Ribbon相关包之后,默认是:RibbonLoadBalancerClient
方法@Override
public ServiceInstance choose(String serviceId) 就是负载均衡的入口
最终通过com.netflix.loadbalancer.IRule#choose(key);方法返回服务实例实现负载均衡
所以,如果在ioc容器中的restTemplate实例,如果切换他的ClientHttpRequestInterceptor就可以实现自己的负载策略了
@Bean
@LoadBalanced
public RestTemplate template(){
MyLoadBalanceInterceptor myLoadBalanceInterceptor = new MyLoadBalanceInterceptor();
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Arrays.asList(myLoadBalanceInterceptor));
return restTemplate;
}

Ribbon有7种负载策略,如何实现负载策略切换呢?

只需要往ioc容器中注入IRule实例就ok了,默认采用的是
private final static IRule DEFAULT_RULE = new RoundRobinRule();轮询

所以,这里如果想要实现自己的负载策略?只需要拿到所有服务列表和服务实例列表就可以自定义实现负载算法了
这里就会牵扯出服务发现算法:类图如下
netflix:
LookupService
EurekaClient
DiscoveryClient
spring cloud:
DiscoveryClient
EurekaDiscoveryClient
EurekaDiscoveryClient属性:
private final EurekaClient eurekaClient;
这个就是netflix的实现DiscoveryClient,这个类会在初始化时,启动2个定时任务:
initScheduledTasks();1 维持心跳(default 30s) 2 刷新本地服务列表(default 30)
所以:
只需要往ioc容器中拿到spring cloud的EurekaDiscoveryClient对象之后,通过方法:
getInstances 所有服务实例
getServices 获得所有服务列表
就可以实现负载均衡策略了

2 再谈Feign的调用
feign中默认是包含了Ribbon相关jar包的
使用步骤:
1 @enable驱动@EnableFeignClients
2 标记接口 @FeignClient
3 注入接口实例(代理对象)
4 调用
源码分析:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients
最主要的任务就是在Import这个注解上:
引入的类:FeignClientsRegistrar
该类实现了 ImportBeanDefinitionRegistrar,在springboot中知道,实现了该类的接口在前置处理时可以注入相应的bean
相应的逻辑就是:去扫描类路径下标记了:@FeignClient的接口,生产相应的动态代理类,通过反射,最终调用RestTemplate实现负载均衡和http调用

你可能感兴趣的:(spring cloud ribbon和Feign的实现原理分析及自定义实现)