一、什么是Ribbon。
Ribbon是Netfix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为。为Ribbon配置服务提供者地址列表后,Ribbon就可基于某种负载均衡算法,自动的去帮助服务消费者去请求。Ribbon默认为我们提供了很多的负载均衡算法,例如轮询、随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。
在实际环境中,当获取的服务列表中就会有多个时,需要编写负载均衡算法,在多个实例列表中进行选择。Eureka中已经帮我们集成了负载均衡组件:Ribbon,简单修改代码即可使用。
二、使用Ribbon实现负载均衡。
1、启动两个服务实例。
2、Eureka 监控面板。
3、开启负载均衡。
因为Eureka中已经集成了Ribbon,所以无需引入新的依赖,直接修改代码即可。
3.1、在RestTemplate的配置方法上添加@LoadBalanced注解:
@SpringBootApplication @EnableDiscoveryClient // 开启Eureka客户端 public class ConsumerDemoApplication { @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(new OkHttp3ClientHttpRequestFactory()); } public static void main(String[] args) { SpringApplication.run(ConsumerDemoApplication.class, args); } }
3.2、修改调用方式。不在手动获取ip和端口 ,而是直接通过服务名称调用:
@Service public class UserService { @Autowired private RestTemplate restTemplate; // Eureka客户端,可以获取到服务实例信息。 @Autowired private DiscoveryClient discoveryClient;// Eureka客户端,可以获取到服务实例信息 public List<User> queryListByIds(List<Long> ids) { List<User> users = new ArrayList<>(); // 地址直接写服务名称 String baseUrl = "http://user-service/user/"; for (Long id : ids) { // 多次查询 users.add(this.restTemplate.getForObject(baseUrl + id, User.class)); // 每次间隔500毫秒 try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } return users; } }
3.3、启动并访问 http://localhost:8082/consumer?ids=1,2
4、负载均衡策略。
Ribbon默认的负载均衡的策略是简单的轮询。
拦截器中是使用RibbonLoadBalanceClient来进行负载均衡的,其中有一个方法choose就是负载均衡的实例方法。
编写测试类,注入choose方法的类对象,然后测试:
@RunWith(SpringRunner.class) @SpringBootTest(classes = ConsumerDemoApplication.class) public class LoadBalanceTest { @Autowired RibbonLoadBalancerClient client; @Test public void test(){ for (int i = 0; i < 100; i++) { ServiceInstance instance = this.client.choose("user-service"); System.out.println(instance.getHost() + ":" + instance.getPort()); } } }
结果:
定义负载均衡的规则接口为IRule,它有以下实现。
SpringBoot也帮我们提供了修改负载均衡规则的配置入口,格式是:{服务名称}.ribbon.NFLoadBalancerRuleClassName
,值就是IRule的实现类。
user-service: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
变为随机:
5、重试机制。
Eureka的服务治理强调了CAP原则中的AP,即可用性和可靠性。它与Zookeeper这一类强调CP(一致性,可靠性)的服务治理框架最大的区别在于:Eureka为了实现更高的服务可用性,牺牲了一定的一致性,极端情况下它宁愿接收故障实例也不愿丢掉健康实例,正如我们上面所说的自我保护机制。
但是,突然停掉某个服务,因为服务剔除的延迟,消费者并不会立即得到最新的服务列表,此时如果我们调用了这些不正常的服务,调用就会失败,从而导致其它服务不能正常工作!
因此Spring Cloud 整合了Spring Retry 来增强RestTemplate的重试能力,当一次服务调用失败后,不会立即抛出一次,而是再次重试另一个服务。
只需要简单配置即可实现Ribbon的重试:
spring: cloud: loadbalancer: retry: enabled: true # 开启Spring Cloud的重试功能 user-service: ribbon: ConnectTimeout: 250 # Ribbon的连接超时时间 ReadTimeout: 1000 # Ribbon的数据读取超时时间 OkToRetryOnAllOperations: true # 是否对所有操作都进行重试 MaxAutoRetriesNextServer: 1 # 切换实例的重试次数 MaxAutoRetries: 1 # 对当前实例的重试次数
根据如上配置,当访问到某个服务超时后,它会再次尝试访问下一个服务实例,如果不行就再换一个实例,如果不行,则返回失败。切换次数取决于MaxAutoRetriesNextServer
参数的值。
引入spring-retry依赖:
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency>
重启user-consumer,测试,发现即使user-service宕机,也能通过另一台服务实例获取结果。
标签:负载,服务,Eureka,实例,均衡,Ribbon From: https://www.cnblogs.com/sfwu/p/16875402.html