Ribbon实现客户端负载均衡

一,前言
在生产环境中,一般微服务都会部署多个实例,那么服务消费者如何将请求分摊到服务提供者身上呢?

二,Ribbon简介
1,Ribbon是Netflix发布的负载均衡器,它有助于控制Http和Tcp客户端行为。为Ribbon配置服务提供者列表后,Ribbon就可基于某种负载均衡算法自动的帮助消费者去请求。Ribbon默认提供的负载均衡算法有:轮询、随机等,也可以自定义实现负载均衡算法。
在Spring Cloud中,Ribbon与Eureka Server配合使用时,可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法去请求其中一个服务提供者实例,如下图所示:


0115.png

2,为消费者整合Ribbon
1),引入依赖


org.springframework.cloud
spring-cloud-starter-netflix-ribbon

2),为RestTemplate添加@LoadBalance注解
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
回顾以前代码,使用以下方法实例化RestTemplate:
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
两者对比发现,只需要添加@LoadBalance注解就可为RestTemplate 整合Ribbon,使其具备负载均衡能力。

3),controller代码如下:
@RestController
@Slf4j
public class UserController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired //注入负载均衡客户端
private LoadBalancerClient loadBalancerClient;

@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
    return this.restTemplate.getForObject("http://movie-provider:8091/" + id, User.class);
}

@GetMapping("/user/list")
public List findAll() {
    return restTemplate.getForObject("http://movie-provider:8091/list", List.class);
}

/**
 * 获取提供者元数据信息
 * @return
 */
@GetMapping("/provider/instance")
public List getServiceInstance(){
    return  discoveryClient.getInstances("movie-provider");
}

/**
 * 打印当前选择的是哪个节点
 * 注意:
 * 不能将restTemplate.getForObject()与loadBalancerClient.choose()写在一个方法中,两者会引起冲突,因为代码中restTemplate实际上
 * 是一个Ribbon客户端,本身已经包含了choose行为。
 */
@GetMapping("/print-instance")
public void printInstance(){
    ServiceInstance serviceInstance = loadBalancerClient.choose("movie-provider");
    log.info("serviceId--->{},host--->{},port--->{}",serviceInstance.getServiceId(),serviceInstance.getHost(),serviceInstance.getPort());
}

}

4),使用java代码自定义Ribbon配置
很多场景下需要使用Ribbon自定义的配置,例如修改Ribbon的负载均衡规则等。Spring Cloud Camden允许使用java代码或者属性自定义Ribbon配置,两种方式是等价的。
在Spring Cloud中,Ribbon的默认配置如下(格式,BeanType beanName:ClassName):


image.png
image.png

4.1 创建Ribbon配置类
@Configuration
public class RibbonConfiguration {
public IRule ribbonRule(){
//负载均衡规则改为随机
return new RandomRule();
}
}
4.2 创建一个类,并在其上添加@Configuration和@RibbonClient注解
/**
*使用@RibbonClient为特定name的Ribbon Client自定义配置
*使用@RibbonClient的configuration属性指定Ribbon的配置类
*/
@Configuration
@RibbonClient(name="movie-provider",configuration = RibbonConfiguration.class)
public class TestConfiguration {
}

你可能感兴趣的:(Ribbon实现客户端负载均衡)