Spring Cloud 负载均衡 Ribbon Spring Cloud 系列之负载均衡 Ribbon的代码实例
Demo_Null 人气:01.1 简介
1.1.1 概述
Ribbon 是 Netflix 发布的负载均衡器,它有助于控制 HTTP 和 TCP 客户端的行为。为 Ribbon 配置服务提供者地址列表后,Ribbon 就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon 默认为我们提供了很多的负载均衡算法,例如轮询、随机等。当然,我们也可为 Ribbon 实现自定义的负载均衡算法。Ribbon 现在已经进入维护状态,但目前仍在大规模使用,Spring Cloud 准备使用 LoadBalancer 作为 Ribbon 的替换方案。
1.1.2 相关依赖
因为现在的注册中心帮我们引入了 Ribbon 我们不需要再次引入就可以直接使用,当然也可以再引入一次没有影响。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency>
1.2 简单使用
1.2.1 搭建项目
1.2.2 开启负载均衡
开启负载均衡非常简单,只需要在 RestTemplate 的配置方法上加上 @LoadBalanced
注解即可使用最简单的轮询。
/** * Created with IntelliJ IDEA. * * @author Demo_Null * @date 2020/10/29 * @description 消费者启动类 */ @SpringBootApplication @EnableDiscoveryClient public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
1.2.3 使用负载均衡
/** * Created with IntelliJ IDEA. * * @author Demo_Null * @date 2020/10/29 * @description */ @RestController @RequestMapping("/consumer") public class ConsumerController { @Autowired private DiscoveryClient discoveryClient; @Autowired private RestTemplate restTemplate; @GetMapping("/go") public void go() { List<ServiceInstance> providerServer = discoveryClient.getInstances("ProviderServer"); if (0 == providerServer.size()) { return; } ServiceInstance serviceInstance = providerServer.get(0); String url = serviceInstance.getUri() + "/provider/get"; System.out.println(url + " --- "); String str = restTemplate.getForObject(url, String.class); System.out.println(str); } }
喔嚯!报错了,明明可以访问到为什么会报找不到实例呢?这是应为咱们使用 DiscoveryClient 直接获取到了服务提供者集群中某一个的地址,然后让 RestTemplate 去进行负载均衡。我们都已经拿到了准确地址再怎么进行负载均衡?所以我们这里不能使用 IP 要使用服务名称。
@RestController @RequestMapping("/consumer") public class ConsumerController { @Autowired private RestTemplate restTemplate; @GetMapping("/go") public void go() { String url = "http://ProviderServer/provider/get"; String str = restTemplate.getForObject(url, String.class); System.out.println(str); } }
修改完毕之后就可以看到服务提供者是轮换进行提供服务的
1.3 替换负载均衡策略
1.3.1 自带负载均衡策略
策略名 | 策略描述 |
---|---|
RoundRobinRule | 轮询选择 server |
RandomRule | 随机选择一个 serve |
RetryRule | 先按轮询策略获取服务,如果获取服务失败则在指定时间内重试,获取可用服务 |
BestAvailableRule | 会先过滤由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务 |
AvailabilityFilteringRule | 会优先过滤故障实例,再选择并发较小的实例 |
WeightedResponseTimeRule | 对轮询的扩展,响应速度越快的实例选择比重权越大,越容易被选择 |
ZoneAvoidanceRule | 复合判断 server 所在区域的性能和 server 的可用性选择 server |
1.3.2 使用配置类
官方文档明确警告,这个自定义配置类不能放在 @ComponedtScan 所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的 Ribbon 客户端所共享。即在 Spring Boot 主程序扫描的包外定义配置类或在与 Spring Boot 主程序的同一级目录但在排除扫描。配置类创建完毕后为 Spring Boo 主程序添加 @RibbonClient 注解引入配置类,用 name 属性来指定调用的服务名称,configuration 属性指定自定义配置类
@Configuration public class MyRibbonRule { @Bean public IRule ribbonRule() { return new RandomRule(); } }
@SpringBootApplication @EnableDiscoveryClient // 用 name 来指定调用的服务名称,configuration 指定自定义配置类 @RibbonClient(name = "ProviderServer", configuration = MyRibbonRule.class) public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
1.3.3 配置文件
# 这种配置的优先级低于配置类 # 想要调用的服务名称,即服务提供者名称 ProviderServer: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
☞ 源码
加载全部内容