Ribbon学习
什么是Ribbon?
目前主流的负载方案分为以下两种:
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端的负载均衡工具,Ribbon客户端组件提供一系列的完善的配置,如超时,重试等。通过Load Balancer获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询,随机)去调用这些服务。Ribbon也可以实现我们自己的负载均衡算法。
客户端的负载均衡
例如spring cloud中的Ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载均衡新算法选择一个服务器,然后进行访问,这是客户端负载均衡;即在客户端就进行负载均衡算法分配。
常见负载均衡算法
nacos-discovery依赖了ribbon,可以不用再引入ribbon依赖。
添加@LoadBalanced注解即可以使用。
@Bean
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder
.setConnectTimeout(Duration.ofSeconds(30L))
.setReadTimeout(Duration.ofSeconds(30L))
.build();
}
全局配置:调用其它微服务时,一律使用指定负载均衡策略
注意:不能写在@SpringBootApplication的@ComponentScan扫描到的地方,否则自定义的配置类就会被所有的RibbonClients共享,不建议这么使用,推荐使用yml的方式:
@Configuration
public class NacosRuleConfiguration {
/**
* 全局配置,调用其它微服务,一律使用指定负载均衡策略
*/
@Bean
public IRule rule() {
// 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机权重)
return new NacosRule();
}
}
@Configuration
public class RoundRobinRuleConfiguration {
@Bean
public IRule rule() {
return new RoundRobinRule();
}
}
/**
* 配置的多个RibbonConfiguration不能被@SpringBootApplication的@ComponentScan扫描到,否则就是全局配置的效果
*/
@SpringBootApplication
@RibbonClients(
value = {
@RibbonClient(name = "test-service", configuration = RoundRobinRuleConfiguration.class),
@RibbonClient(name = "stock-service", configuration = NacosRuleConfiguration.class)
})
局部配置:调用指定微服务提供的服务时,使用对应的负载均衡算法
修改application.yml
# order-service 被调用的服务名
order-service:
ribbon:
# 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重)
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
IRule:
这是所有负载均衡策略的父接口,里边的核心方法就是choose方法,用来选择一个服务实例。
AbstractLoadBalancerRule:
AbstractLoadBalancerRule是一个抽象类,里边主要定义了一个ILoadBalancer,就是我们上文所说的负载均衡器。这里定义它的目的主要是辅助负责均衡策略选取合适的服务端实例。
自定义负载均衡策略实现(简单示例,可能存在并发问题):
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class CustomRule extends AbstractLoadBalancerRule {
@Override
public Server choose(Object key) {
// 获取当前服务请求的实例
List<Server> servers = this.getLoadBalancer().getReachableServers();
// 获取随机数下标
int random = ThreadLocalRandom.current().nextInt(servers.size());
// 获取服务实例
Server server = servers.get(random);
if (server.isAlive()) {
return server;
}
return null;
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
按照上面方法配置生效。
开启饥饿加载模式,解决第一次调用慢的问题
ribbon:
eager-load:
# 开启饥饿加载模式
enabled: true
# 配置stock-service使用饥饿加载,多个使用逗号分隔
clients: stock-service
什么是Spring Cloud LoadBalancer?
Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器,用来替代Ribbon。
Spring官方提供了两种负载均衡的客户端:
RestTemplate:
RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。默认情况下,RestTemplate默认依赖jdk的HTTP连接工具。
WebClient:
WebClient是从Spring WebFlux 5.0版本开始提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具。它的响应式编程的基于Reactor的。WebClient中提供了标准Http请求方式对应的get、post、put、delete等方法,可以用来发起相应的请求。