Spring Cloud: Ribbon实现负载均衡
在实际应用中,对于服务提供者user-service,我们会开启多个集群,此时我们获取到多个服务列表,我们该如何选择使用哪一个服务呢?一般情况下,我们需要自己写负载均衡算法来选择合适的服务,不过在Eureka中已经实现了负载均衡组件:ribbon。
1.简介
Ribbon是NetFlix发布的负载均衡器,它有助于控制Http和TCP客户端的行为。为Ribbon配置服务提供者地址列表后,Ribbon就可以基于某种负载均衡算法,自动的帮助服务消费者去请求。Ribbon默认提供了很多负载均衡算法,例如轮询、随机等,当然,我们也可以为Ribbon实现自定义的负载均衡算法。
2.Ribbon实现
启动两个user-service实例,端口号分别为10001和10002,启动eureka,Eureka端口号为10000,访问localhost:10000
可以看到两个user-service已经注册到Eureka了。
开启负载均衡,由于Eureka中已经集成了Ribbon,所以不需要在引入依赖,直接在RestTemplate配置方法添加@LoadBalanced注解
@SpringBootApplication
@EnableDiscoveryClient //开启Eureka客户端发现功能
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
修改调用方式,不在通过手动方式获取ip和端口,而是通过服务器名称调用
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/{id}")
public User queryById(@PathVariable Long id){
String url="http://user-service/user/"+id;
return restTemplate.getForObject(url,User.class);
}
}
启动Eureka、服务端和客户端,访问页面,查看控制台
Ribbon的默认负载均衡策略是简单的轮询,我们可以写个测试类进行验证,在ribbon中使用的RibbonLoadBalanceClient来进行负载均衡的,其中有有一个choose方法是负载均衡获取实例的,注入这个类的对象,进行测试。
@RunWith(SpringRunner.class)
@SpringBootTest
public class LoadBalanceTest {
@Autowired
private RibbonLoadBalancerClient client;
@Test
public void test(){
for(int i=0;i<10;i++){
ServiceInstance instance = client.choose("user-service");
System.out.println(instance.getHost()+":"+instance.getPort());
}
}
}
启动测试类,查看控制结果,发现10001和10002交替出现,证明负载均衡算法采用的是轮询的方式。
SpringBoot也提供了修改负载均衡规则的配置入口,格式是{服务名}ribbon.NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule ,值就是IRule的实现类
user-service:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
再次测试,发现负载均衡采用了随机的方式。