简介
Ribbon是SpringCloud体系中用来实现负载均衡的组件。Ribbon提供一系列完善的配置项,如连接超时,重试等。主要功能是提供客户端的软件负载均衡算法和服务调用。简单说就是在配置文件中列出Load Balancer后面的所有机器,Ribbon会自动的基于某种规则(简单轮询,随即链接等)去连接这些机器。可以实现自定义负载均衡算法。
作用
负载均衡
负载均衡就是将用户的请求平摊的多个服务上,从而达到系统的高可用。
负载均衡分类
集中式负载均衡:消费方和提供方之间使用独立的负载均衡设施,由该设施负责将请求转发至服务提供方。
进程内负载均衡:逻辑集成到消费方,从注册列表中获取一个合适的提供方,将请求转发至提供方。
负载均衡
负载均衡策略
- BestAvailableRule最少并发数策略:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
- AvailabilityFilteringRule可用性敏感策略: 先过滤掉故障实例,再选择并发较小的实例
- ZoneAvoidanceRule区域性敏感策略:复合判断server所在区域的性能和server的可用性选择服务器
- RandomRule随机
- RetryRule重试策略
- RoundRobinRule轮询(默认策略)
- ResponseTimeWeightedRule响应时间权重:响应时间越短,权重越大,下次越有可能被选中
- WeightedResponseTimeRule:响应速度越快的实例选择权重越大,越容易被选择
Ribbon负载均衡策略配置
①搭建Spring Cloud项目(任选其一,推荐选3)
②在消费者项目中创建自定义的规则要类MyRule,自定义的规则要类不要放在启动类所在的包下。官方要求自定义的规则要放在@ComponentScan扫描不到的包下。因为@SpringBootApplication包含@ComponentScan注解,@ComponentScan会扫描他所在的包以及子包下的所有类,因此MyRule不能放在启动类所在的包下
③编辑自定义的规则要类MyRule。
@Configuration public class MyRule { @Bean public IRule getRandomRule() { //可以从上面中的策略中选一个 return new RandomRule(); //随机分配策略 } }
④编辑启动类,添加@RibbonClient,@EnableDiscoveryClient注解
//name 服务提供者名字,configuration 自定义规则类名 @RibbonClient(name = "cloud-provider", configuration = MyRule.class) @EnableDiscoveryClient @SpringBootApplication public class ConsumerConsul80 { public static void main(String[] args) { SpringApplication.run(ConsumerConsul80.class, args); } }
⑤创建ApplicationContextConfig类,将RestTemplate注入到容器里面
@Configuration public class ApplicationContextConfig { @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
⑥创建controller
@RestController @RequestMapping("consumer") public class ConsumerController { private static final String URL = "http://cloud-provider/provider"; @Autowired private RestTemplate restTemplate; @GetMapping("getUUID") public String getUUID() { return restTemplate.getForObject(URL + "/getUUID", String.class); } }
测试
启动注册中心
启动服务提供者
①首先对服务提供者controller进行改造,返回的数据前面加上端口号,方便观察
@RestController @RequestMapping("provider") public class ProviderController { @Value("${server.port}") private String port; @GetMapping("getUUID") public String getUUID() { return port + " : " + UUID.randomUUID(); } }
②启动服务提供者ProviderConsul8001
③启动服务提供者ProviderConsul8002
④启动服务提供者ProviderConsul8003
启动服务消费者
查看结果
因为我们选择的是随机分配,所以返回的端口号是随机的。