负载均衡的实现方式
@RibbonClient
@LoadBalanced
@LoadBalanced实现负载均衡的代码如下:
1 |
|
restTemplate调用:
1 |
|
@LoadBalanced注解的原理可参考:
Robbon负载均衡源码分析
RestTemplate
进入restTemplate的getForObject方法,进行一系列的调用,最终会进入到doExecute方法中,将请求信息封装为ClientHttpRequest对象,调用它的execute方法执行请求:
1 | public class RestTemplate extends InterceptingHttpAccessor implements RestOperations { |
HttpAccessor
调用createRequest方法是在HttpAccessor类中实现的,在该方法中调用了getRequestFactory获取RequestFactory,由于RestTemplate继承了InterceptingHttpAccessor,InterceptingHttpAccessor又继承了HttpAccessor,所以执行getRequestFactory的时候会进入到InterceptingHttpAccessor的getRequestFactory创建请求:1
2
3
4
5
6
7
8
9
10
11
12
13public abstract class HttpAccessor {
// 默认是SimpleClientHttpRequestFactory
private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
// 使用工厂模式创建ClientHttpRequest
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
ClientHttpRequest request = getRequestFactory().createRequest(url, method);
if (logger.isDebugEnabled()) {
logger.debug("HTTP " + method.name() + " " + url);
}
return request;
}
}
InterceptingHttpAccessor
在InterceptingHttpAccessor中的getRequestFactory中,会判断拦截器是否为空,如果不为空判断当前RequestFactory是否为空,如果为空将创建一个InterceptingClientHttpRequestFactory类型的工厂:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public abstract class InterceptingHttpAccessor extends HttpAccessor {
public ClientHttpRequestFactory getRequestFactory() {
// 获取拦截器
List<ClientHttpRequestInterceptor> interceptors = getInterceptors();
// 如果拦截器不为空
if (!CollectionUtils.isEmpty(interceptors)) {
ClientHttpRequestFactory factory = this.interceptingRequestFactory;
// 如果factory为空
if (factory == null) {
// 创建InterceptingClientHttpRequestFactory
factory = new InterceptingClientHttpRequestFactory(super.getRequestFactory(), interceptors);
this.interceptingRequestFactory = factory;
}
return factory;
}
else {
return super.getRequestFactory();
}
}
}
InterceptingClientHttpRequestFactory
InterceptingClientHttpRequestFactory当然创建的是InterceptingClientHttpRequest类型的请求类,所以最终会进入到InterceptingClientHttpRequest的execute方法中:1
2
3
4
5
6
7
8
9
10public class InterceptingClientHttpRequestFactory extends AbstractClientHttpRequestFactoryWrapper {
private final List<ClientHttpRequestInterceptor> interceptors;
protected ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod, ClientHttpRequestFactory requestFactory) {
return new InterceptingClientHttpRequest(requestFactory, this.interceptors, uri, httpMethod);
}
}
InterceptingClientHttpRequest
InterceptingClientHttpRequest继承了AbstractClientHttpRequest,它们都是ClientHttpRequest的子类,InterceptingClientHttpRequest中有一个内部类InterceptingRequestExecution,它有一个拦截器类型的ClientHttpRequestInterceptor迭代器iterator,还实现了execute方法,在execute方法中会获取拦截器,对请求进行拦截:
1 | class InterceptingClientHttpRequest extends AbstractBufferingClientHttpRequest { |
ClientHttpRequestInterceptor的实现类如下:
LoadBalancerInterceptor
进入到LoadBalancerInterceptor拦截器中,查看拦截器的intercept方法,在该方法中调用了LoadBalancerClient的execute方法执行请求,也就是说请求会被负载均衡拦截器所拦截,然后调用负载均衡客户端 LoadBalancerClient的execute方法执行请求:
1 | public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor { |
RibbonLoadBalancerClient
LoadBalancerClient是一个接口,RibbonLoadBalancerClient实现了它,在execute方法中,首先调用getLoadBalancer方法获取LoadBalancer的实现类,选取一个负载均衡实现类,默认情况下会返回ZoneAwareLoadBalancer的负载均衡器,然后调用getServer(在此方法中又调用了chooseServer),根据负载均衡规则选取一个服务,之后就知道往哪个服务上发送请求,执行发送请求操作了:
1 | public class RibbonLoadBalancerClient implements LoadBalancerClient { |
负载均衡策略
ILoadBalancer
ILoadBalancer是一个接口:
1 | public interface ILoadBalancer { |
BaseLoadBalancer中实现了chooseServer方法,在BaseLoadBalancer中有一个默认的负载均衡策略是RoundRobinRule:
1 | public class BaseLoadBalancer extends AbstractLoadBalancer implements |
七种负载均衡策略
- RoundRobinRule
- RandomRule
- AvailabilityFilteringRule
- WeightedResponseTimeRule
- RetryRule
- BestAvailableRule
- ZoneAvoidanceRule
参考:
【掘金小册】LinkedBear:SpringCloudNetflix 源码解读与原理分析
SpringBoot版本:2.1.9
SpringCloud版本: Greenwich.SR4