负载均衡Ribbon
1、什么是Ribbon
ribbon是基于netflix 实现的一个工作在consumer端的负载均衡工具,提供了很多负载均衡策略:轮询、随机等。
2、实现自定义负载均衡
2.1、创建服务提供者
2.1.1、创建工程provider
2.1.2、application.yml
server:
port: 9090
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.216.133:8848
application:
name: ribbon-provider
server:
port: 9091
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.216.133:8848
application:
name: ribbon-provider
2.2、创建服务消费者
2.2.1、创建工程nacos_consumer
2.2.2、application.yml
server:
port: 80
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.216.133:8848
application:
name: ribbon-consumer
2.2.3、controller
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;//发现服务的工具类
private int index;
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id) {
List<String> serviceList = discoveryClient.getServices();
//随机方式获得服务
int currentIndex = new Random().nextInt(2);
//轮询方式获得服务
//index = index + 1;
//int currentIndex =(index)% serviceList.size();
获取nacos中注册的指定服务信息
ServiceInstance instance = discoveryClient.getInstances("ribbon-provider").get(currentIndex);
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/provider/getUserById/" + id;
return restTemplate.getForObject(url, User.class);
}
}
3、什么是负载均衡
负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上进行执行。
3.1.开启ribbon负载均衡
@Bean
@LoadBalanced//开启ribbon负载均衡,默认是轮询策略
public RestTemplate restTemplate(){
return new RestTemplate();
}
添加了@LoadBalanced注解之后,Ribbon会给restTemplate请求添加一个拦截器,在拦截器中获取 注册中心的服务列表,并使用Ribbon内置的负载均衡算法从服务列表里选中一个服务,通过获取到的服务信息 (ip,port)替换 serviceId 实现负载请求。
3.2、指定负载均衡的策略
//随机策略
@Bean
public IRule iRule() {
return new RandomRule();
}
负载均衡实现 | 策略 |
---|---|
随机策略:RandomRule | 从服务提供者的列表中随机选择一个服务实例 |
轮询策略:RoundRobinRule | 按照一定的顺序依次调用服务实例 |
可用敏感性策略:AvailabilityFilteringRule | 先过滤掉由于多次访问故障的服务,以及并发连接数超过阈值的服务,然后对剩下的服务按照轮询策略进行访问 |
权重策略:WeightedResponseTimeRule | 根据平均响应时间计算所有服务的权重,响 应时间越快服务权重就越大被选中的概率即越高,如果服务刚启动时统计信息不足,则 使用RoundRobinRule策略,待统计信息足够会切换到该WeightedResponseTimeRule策略 |
重试负载均衡策: RetryRule | 先按照 RoundRobinRule 策略获取 provider,若获取失败,则在指定的时限内重试。默认的时限为 500 毫秒。 |
最小连接数策略:BestAvailableRule | 先过滤掉由于多次访问故障的服务,然后选择一个并发量最小的服务 |
区域敏感策略:ZoneAvoidanceRule | 综合判断服务节点所在区域的性能和服务节点的可用性,来决定选择哪个服务 |
3.3、发送请求
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;//发现服务的工具类
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id) {
String url = "http://ribbon-provider/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
}
4、ribbon存在的问题
url和参数还需要拼接,效率太低,不利于维护。
优化方法详见 下一篇:Spring Cloud Alibaba 微服务 --------声明式服务调用Feign