负载均衡原理
LoadBalancerInterceptor
实现 ClientHttpRequestInterceptor
接口
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {...}
进入ClientHttpRequestInterceptor
查看干什么:Client Http Request Interceptor
本意是客户端Http请求拦截器。也就是它会拦截由客户端发起的http请求。而我们RestTemplate
正是发起请求的客户端。
public interface ClientHttpRequestInterceptor {
ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException;
}
返回刚才实现类,既然是实现这个接口,那么就会实现这个接口的方法。RestTemplate
发起请求一定会被此方法拦截,我们可以打断点调试查看。
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));
}
}
访问浏览器http://localhost:8080/order/102后,程序就会停在我们刚才断点处,发现请求是被获取了,而且还得到我们配置服务名称。
既然拿到服务名称,那接下来就需要到Eureka进行服务拉取。他把服务名称交给loadBalancer
处理,而loadBalancer
是一个BlockingLoadBalancerClient对象。execute是执行,继续跟入此方法。
我们就到BlockingLoadBalancerClient,继续跟进
负载均衡策略
第一种方式是全局的,以后无论调用哪种服务都会采用随机策略。而第二种方案则可以指定服务采用哪种负载均衡策略。
定义IRule方式
package cn.itcast.order;
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
//....
@Bean
public IRule randomRule(){
return new RandomRule();
}
}
依次访问http://localhost:8080/order/下的101、102、103、104
注意:小范围测试可能都会映射再一个服务地址上,当访问次数大,总体上就是随机概率。
配置文件方式
userservice:
ribbon:
NFloadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
懒加载
Ribbon默认是采用懒加载,即第一次访问时才会去创LoadBalanceClient
,请求时间会很长。而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:
ribbon:
eager-load:
enabled: true # 开启饥饿加载
clients: userservice # 指定对userservice这个服务饥饿加载
ribbon:
eager-load:
enabled: true
clients:
- userservice1 #如果有多个服务需要就以下那么配置
- userservice2