目录
一、简介
1.什么是ribbon?
ribbon是基于netflix ribbon实现的一个工作在consumer端的负载均衡工具(言外之意是工作在消费端的),提供了很多负载均衡策略:轮询、随机...
我们不需要去引入ribbon的依赖,因为在nacos里面已经集成了ribbon的依赖:
2.什么是负载均衡
通俗的讲,负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上进行执行。
二、ribbon入门
1.自定义实现负载均衡
分别创建服务提供者两个模块
配置文件application.yml中分别设置不同的端口号:
server:
port: 9090
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.238.132:8848
application:
name: ribbon-provider
server:
port: 9091
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.238.132:8848
application:
name: ribbon-provider
两个服务提供者的controller分别为:
@RestController
@RequestMapping("/provider")
public class ProviderController {
@Autowired
private UserService userService;
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
return userService.getUserById(id);
}
}
两个服务提供者的service分别为以下内容,名字:
public interface UserService {
User getUserById(Integer id);
}
service实现层分别为:
@Service
public class UserServiceImpl implements UserService {
@Override
public User getUserById(Integer id) {
return new User(id,"王小-1",18);
}
}
@Service
public class UserServiceImpl implements UserService {
@Override
public User getUserById(Integer id) {
return new User(id,"王小-2",18);
}
}
在创建一个服务消费者模块:
配置文件application.yml为:
server:
port: 80
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.238.132:8848 #nacos服务的地址
application:
name: nacos-consumer #向注册中心注册的名字
controller中分别使用了两种方式:随机方式和轮询方式进行测试:
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
//访问Rest服务的客户端
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
private int index;
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
List<String> servicesList = discoveryClient.getServices();
//随机方式获得服务
//int currentIndex=new Random().nextInt(2);
//轮询方式获得服务
index=index+1;
int currentIndex=(index)%servicesList.size();
ServiceInstance instance = discoveryClient.getInstances("ribbon-provider").get(currentIndex);
String serviceUrl = instance.getHost() + ":" + instance.getPort();
String url="http://"+serviceUrl+"/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
}
测试结果:
随机方式的测试结果:通过不断的刷新,和查看可以得知随机方式,是随意的获取到服务,没有固定规律而言;
轮询方式的测试结果:通过不断的刷新,和查看,可以的得知轮询方式是获取到一个服务后,在次刷新就会获取下一个服务,是来回轮流着获取
2.负载均衡策略
这里只举出两个例子:随机策略、轮询策略
负载均衡接口:com.netflix.loadbalancer.IRule
1. 随机策略
com.netflix.loabancer.RandomRule:该策略实现了从服务清单中随机选择一个服务实例的功能。
2.轮询策略
com.netflix.loadbalancer.RoundRobinRule:该策略实现按照线性轮询的方式依次选择实例的功能。具体实现如下,在循环中增加了一个count计数变量,该变量会在每次轮询之后累加并求余服务总数。
3.基于ribbon实现负载均衡
1.开启ribbon负载均衡:默认是轮询策略
@Configuration
public class ConfigBean {
@Bean
/**
* 添加了@LoadBalanced注解之后,Ribbon会给restTemplate请求添加一个拦截器,
* 在拦截器中获取注册中心的服务列表,并使用Ribbon内置的负载均衡算法从服务列表
* 里选中一个服务,通过获取到的服务信息(ip,port)替换 serviceId 实现负载请求。
*/
@LoadBalanced //开启负载均衡
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
2.指定负载均衡策略
在ConfigBean配置类中添加以下内容,将会变成随机策略
//随机策略
@Bean
public IRule iRule() {
return new RandomRule();
}
3.修改ribbon_consumer服务消费者模块
controller层
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
//访问Rest服务的客户端
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
//@LoadBalanced会将ribbon-provider替换成ip和端口
String url="http://ribbon-provider/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
三、ribbon的问题
1、还需要拼接url和参数,效率太低
2、默认不能剔除死亡的服务