一. Ribbon简介
Ribbon是Netfilx发布的负载均衡器,有助于控制HTTP和TCP客户端的行为。为Ribbon配置服务提供者地址列表后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多的负载均衡算法,例如轮询,随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可以自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。
二. 相关实践
1. Eureka整合Ribbon
<1> 配置pom文件
引入Ribbon依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
注意:如果引入了下列jar包,由于该依赖已经包含了Ribbon,所以不需要再重新引入Ribbon。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<2> 配置RestTemplate
为RestTemplate增加@LoadBalanced注解:
@Bean
@LoadBalanced
public RestTemplate getRestTemplate () {
return new RestTemplate();
}
<3> 在Controller中进行远程调用
@Autowired
private RestTemplate restTemplate;
@GetMapping("/{id}")
public User selectUser (@PathVariable("id") int id) {
return restTemplate.getForObject("http://zz-provider-user/user/" + id, User.class);
}
注意:
1.只需要为RestTemplate添加@LoadBalanced注解,就可以为RestTemplate整合Ribbon,使其具备负载均衡的能力。
2.调用loadBalancerClient.choose("zz-provider-user"),会基于Eureka上的消费者列表根据负载均衡算法选择一个消费者实例。
3.不能将加了@LoadBalanced注解的restTemplate.getForObject(...)与loadBalanceClient.choose(...)写在同一个方法中,两者之间会冲突。因为加了@LoadBalanced注解的restTemplate其实是一个Ribbon客户端,本身已经包含了"choose"的行为。
2. 使用JavaConfig自定义Ribbon配置
很多场景下,需要自定义Ribbon的配置,例如修改Ribbon的负载均衡规则。
Spring Cloud允许使用JavaConfig或者属性来自定义Ribbon配置,两种方式是等价的。
<1> 配置 RibbonConfiguration
@Configuration
public class RibbonConfiguration {
@Bean
public IRule ribbonRule () {
//负载均衡规则,改为随机
return new RandomRule();
}
}
<2> 配置RibbonClientConfiguration
@Configuration
@RibbonClient(name = "zz-provider-user", configuration = RibbonConfiguration.class)
public class RibbonClientConfiguration {
}
注意:本例中的RibbonConfiguration类不能包含在主应用程序上下文的@ComponentScan中,否则该类中的配置信息会被所有的@RibbonClient共享。因此,如果只想针对某一个Ribbon客户端自定义配置,必须防止该自定义配置被@ComponentScan扫描到,或者显示指定@ComponentScan不扫描该自定义配置。
3. 使用属性自定义Ribbon配置
从Spring Cloud Netflix1.2.0开始,Ribbon支持使用属性自定义Ribbon客户端。
支持的属性如下(配置的前缀是<clientName>.ribbon):
NFLoadBalancerClassName:配置ILoadBalancer的实现类
NFLoadBalancerRuleClassName:配置IRule的实现类
NFLoadBalancerPingClassName:配置IPing的实现类
NIWSServerListClassName:配置ServerList的实现类
NIWSServerListFilterClassName:配置ServerListFilter的实现类
举例:在项目的application.yml中添加以下内容:
zz-provider-user:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
4. 脱离Eureka使用Ribbon
一般Ribbon和Eureka会配合使用。但可能会有特殊情况。例如某些遗留的微服务,它们没有注册到Eureka Server上,甚至根本不是Spring Cloud开发,此时如果需要使用Ribbon实现负载均衡,该如何做?Ribbon支持脱离Eureka使用!
<1> 配置pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<2> 配置application.yml
zz-provider-user:
ribbon:
listOfServers: localhost:8000,localhost:8001
该属性为名字为zz-provider-user的Ribbon客户端设置请求的地址列表。