@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }
RestTemplate对象加上LoadBalanced注解就是作了个标记,标记着RestTemplate对象发起的Http请求要被拦截和处理
LoadBalancerInterceptor对象来完成拦截的动作,查看其源码
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor { private LoadBalancerClient loadBalancer; private LoadBalancerRequestFactory requestFactory; public LoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory) { this.loadBalancer = loadBalancer; this.requestFactory = requestFactory; } public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) { this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer)); } public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution)
throws IOException { URI originalUri = request.getURI(); String serviceName = originalUri.getHost(); Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri); return (ClientHttpResponse)this.loadBalancer.execute(serviceName,
this.requestFactory.createRequest(request, body, execution)); } }
查看ClientHttpRequestInterceptor接口
ClientHttpRequestInterceptor作用就是拦截客户端 HTTP 请求
LoadBalancerInterceptor实现了ClientHttpRequestInterceptor接口中intercept方法,说明LoadBalancerInterceptor可以完成拦截客户端 HTTP 请求
在intercept方法中添加断点,Debug查看
进入execute
通过Ribbon完成从eureka拉取服务信息
根据服务名获取DynamicServerListLoadBalancer对象,DynamicServerListLoadBalancer对象包含Rule和服务信息
进入getServer方法,获取服务
进入chooseServer方法,选择一个服务
根据rule(规则)选择服务,其默认规则为:ZoneAvoidanceRule
最终结果:
Ribbon负载均衡整体流程:
Ribbon负载均衡具体流程: