3 负载均衡 Spring Cloud Ribbon

目录

1 Ribbon 简介

 2 入门案例

2.1 启动多个服务生产者,搭建集群

2.2 开启消费者负载均衡

3 Ribbon负载均衡源码研究


1 Ribbon 简介

  • Ribbon 是实现了HTTP和TCP的客户端负载均衡的工具
  • Ribbon是一个工具框架,实现了HTTP和TCP的客户端负载均衡的工具
  • 可以将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用
  • Ribbon 不是一个微服务,不需要独立部署
  • Ribbon 几乎存在于每一个Spring Cloud构建的微服务和基础设施中
  • 因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的
  • Feign也是基于Ribbon实现的工具

Ribbon所提供的负载均衡算法:

  • 轮询(RoundRobinRule):拿到所有的server集合,然后根据id进行遍历。这里的id是ip+端口,当轮询了10个服务端节点还没有找到可用服务的话,轮询结束。
  • 随机(RandomRule):使用jdk自带的随机数生成工具,生成一个随机数,然后去可用服务列表中拉取服务节点Server。如果当前节点不可用,则进入下一轮随机策略,直到选到可用服务节点为止。
  • 可用过滤(AvailabilityFilteringRule,Ribbon默认策略):过滤掉连接失败的服务节点,并且过滤掉高并发的服务节点,然后从健康的服务节点中,使用轮询策略选出一个节点返回。
  • 响应时间权重(WeightedResponseTimeRule):根据响应时间,分配一个权重weight,响应时间越长,weight越小,被选中的可能性越低。
  • 轮询失败重试(RetryRule):首先使用轮询策略进行负载均衡,如果轮询失败,则再使用轮询策略进行一次重试,相当于重试下一个节点,看下一个节点是否可用,如果再失败,则直接返回失败。重试的时间间隔,默认是500毫秒,我们可以自定义这个重试时间间隔。
  • 并发量最小可用(BestAvailableRule)选择一个并发量最小的server返回。如何判断并发量最小呢?ServerStats有个属性activeRequestCount,这个属性记录的就是server的并发量。轮询所有的server,选择其中activeRequestCount最小的那个server,就是并发量最小的服务节点。
  • 区域避免(ZoneAvoidanceRule):复合判断server所在区域的性能和server的可用性,来选择server返回。

 2 入门案例

步骤1: 启动多个user_service服务

  • 修改配置文件端口获取方式
  • 编辑应用启动配置
  • 启动3个提供者服务
  • 在注册中心查询是否启动成功

步骤2:开启消费者负载均衡

  • 在RestTemplate的注入方法上加入@LoadBalanced注解
  • 修改调用请求的Url地址,改为服务名称调用
  • 访问页面查看效果

2.1 启动多个服务生产者,搭建集群

如何开启多个user_service服务?多个同样的服务之间的差别就在端口号上,如下介绍了如何通过IDEA搭建一个简单的服务集群。

 完成上面的步骤后,启动那三个服务,然后去看看有没有被注册上去:

2.2 开启消费者负载均衡

在服务消费者启动引导类中RestTemplate的注入方法上增加注解@LoadBalanced,从而开启restTemplate对象支持负载均衡的能力,如下:

@SpringBootApplication
@EnableDiscoveryClient //开启注册中心客户端的自动配置
public class ConsumerServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerServiceApplication.class, args);
    }
    /**
     * 让消费者支持负载均衡:只需要在RestTemplate注入方法上加一个@LoadBalanced注解即可!
     */
    @Bean //相当于 applicationContext.xml中的bean标签
    @LoadBalanced //开启restTemplate对象支持负载均衡的能力
    //一旦开启,请求时传统的url地址 http://127.0.0.1:9091/user/findById?id=1 就不能用了
    // 而是用负载均衡地址: http://user-service/user/findById?id=1
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

在使用RestTemplate发送http请求时,此时的请求url不能是http://host:port/a/b的形式了!host:port的部分必须是要访问服务的服务名(集群名字),而这个名字是这些服务注册到Eureka上的名字!

/**
 * 消费者的控制层,提供服务,访问提供者接口,为真实用户返回信息
 */
@RestController
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;
  
    /**
     *  让消费者支持负载均衡:也就是说原来消费者直接访问目标服务,但是现在具备同样功能的服务有多个
     *  负载均衡实现了消费者具体访问哪一个服务
     */
    @RequestMapping("/ribbonconsumer/{id}")
    public User ribbonFindById(@PathVariable("id") Integer id){
        //负载均衡访问服务,此时的访问地址中host和port部分变成了被访问服务的名称
        //注意:restTemplate一旦使用了负载均衡,传统的url访问就不能用了!也就是说上面那个方法findById已经不适用了
        //因为现在的做法是通过服务名字,再结合负载均衡器去选取适当的服务,
        // 如果还是沿用url访问的话会将“host+port”当成服务名字去eureka中找对应的服务集群,这样当然是找不到的!
        String url = "http://user-service/user/findById?id="+id;
        User user = restTemplate.getForObject(url, User.class);
        return user;
    }
}

测试:访问 http://localhost:8080/ribbonconsumer/1

Ribbon默认的负载均衡策略是AvailabilityFilteringRule
修改负载均衡策略的方法如下:

# 修改服务消费者配置文件:将默认的负载均衡策略改为轮询
user-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

3 Ribbon负载均衡源码研究

负载均衡器动态访问的本质,是从服务注册中心中获取服务提供者的访问地址(host、port)。
这个过程显然是有某个组件,根据Service名称去获取了服务实例ip和端口。
那么这个组件经过源码分析就是LoadBalancerInterceptor
这个负载均衡拦截器的类,会对RestTemplate的请求进行拦截,然后从服务清单中
获取服务集群的所有地址,随后利用负载均衡算法得到真正服务地址信息进行访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值