负载均衡
- 1. Ribbon简单描述
- 2. 在SpringCloud中查看相关处理源码
- 3. ribbon的默认策略,懒加载
- 3. 实操中的相关问题
1. Ribbon简单描述
Spring Cloud Ribbon 是一套基于 Netflix Ribbon 实现的客户端负载均衡和服务调用工具。Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。
----来自百度
简单的说,这个Ribbon就是由netfix开发的一套用于转接请求的工具(除了自带的一些轮询、随机方式,也可以手动编译自己的负载均衡方式)。
即使用顺序发起请求
-》到达ribbon
->调用eurake
;
我记得ngnix也是存在负载均衡的?没错,ngnix也自带一个负载均衡,为轮询、最少连接等
2. 在SpringCloud中查看相关处理源码
- 在ribbon的负载均衡中,主走的配置类名称为:LoadBalancerInterceptor;实现接口为:ClientHttpRequestInterceptor(专门拦截住客户端发起的请求);
- 相关轮询的规则:所有规则的父类接口为IRule,其中实现了几个主要的方法:com.netflix.loadbalancer.IRule#choose(实现服务选择);
- 调整IRule,即只需要重新定义一个对应的IRule规则,并将其放入容器,后续读取的时候便会按照这个来,如你可以实现一个类,继承IRule;这样可以自定义具体的规则。当然,普遍可以直接应用已经存在的规则,而无需自己去重新定义。
// 定义一个类
public class NewRule implements AbstractLoadBalancerRule{
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
@Override
public Server choose(Object key) {
return null;
}
public NewRule() {
super();
}
}
// 在启动类中,将对应的新增规则放入容器即可。
@Bean
public IRule randomRule() {
return new NewRule();
}
ribbon默认实现的是ZoneAvoidanceRule规则
,这个规则的基本描述是可以定好服务区的范围,然后在这个范围内去轮询,一般情况下,可能就是所有的服务直接轮询,因为很多公司服务可能都在一起,
3. ribbon的默认策略,懒加载
ribbon:
eager-load:
enabled: true #默认为false,表示ribbon是需要等到使用的时候才加载;;
clients: userservice # 配置为 懒加载的服务
3. 实操中的相关问题
- 在这里我一开始用template调用其它模块的接口时,发现,eurake可以读取到正确的接口,但是却总是报错,连接失败:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://*****/***/***": Connection timed out: connect; nested exception is java.net.ConnectException: Connection timed out: connect] with root cause java.net.ConnectException: Connection timed out: connect
;
由于一直看不出代码哪里有问题,于是怀疑是不是一开始的配置就不对,百度后,在网上发现有人也出现过类似的问题,且都是配置上过期的时间就会恢复正常。如下:
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setConnectTimeout(10*1000);
requestFactory.setReadTimeout(10*1000);
return new RestTemplate(requestFactory);
}
通过上面的RestTemplate配置一下具体入参HttpComponentsClientHttpRequestFactory ;在默认的情况下,如果不配置具体的超时时间,就会一直抛出超时异常,目前都没弄明白为什么。
等后续学的差不多了统一把这些问题都过一下;;