Spring Cloud 负载均衡

1. Ribbon 客户端负载均衡

1.1 Ribbon 概述

  • Ribbon 是 Netflix 提供的一个基于 HTTP 和 TCP 的客户端负载均衡工具
  • Ribbon主要有两个功能:
    • 简化远程调用
    • 负载均衡

客户端负载均衡和服务端负载均衡的区别

服务端负载均衡

  • 负载均衡算法在服务端
  • 由负载均衡器维护服务地址列表

在这里插入图片描述

客户端负载均衡

  • 负载均衡算法在客户端
  • 客户端维护服务地址列表

在这里插入图片描述

1.2 Ribbon 远程调用

Ribbon 可以简化 RestTemplate 的远程调用。

原来的 Provider 中的远程调用如下:

@GetMapping("/goods/{id}")
public Goods findGoodsById(@PathVariable("id") int id){

    //演示discoveryClient 使用
    List<ServiceInstance> instances = discoveryClient.getInstances("eureka-provider");

    //判断集合是否有数据
    if(instances == null || instances.size() == 0){
        //集合没有数据
        return null;
    }

    ServiceInstance instance = instances.get(0);
    String host = instance.getHost();//获取ip
    int port = instance.getPort();//获取端口

    System.out.println(host);
    System.out.println(port);

    String url = "http://"+host+":"+port+"/goods/findOne/"+id;
    // 3. 调用方法
    Goods goods = restTemplate.getForObject(url, Goods.class);

    return goods;
}

使用 Ribbon 简化 restTemplate 调用:

  1. 在声明 restTemplate 的 Bean 时候,添加一个注解:@LoadBalanced

    @Configuration
    public class RestTemplateConfig {
        @LoadBalanced
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    
  2. 在使用 restTemplate 发起请求时,需要定义 url 时,host:port 可以替换为服务提供方的应用名称

    @GetMapping("/goods2/{id}")
    public Goods findGoodsById2(@PathVariable("id") int id){
        String url = "http://EUREKA-PROVIDER/goods/findOne/"+id;
        // 3. 调用方法
        Goods goods = restTemplate.getForObject(url, Goods.class);
    
        return goods;
    }
    

1.3 Ribbon 负载均衡

  1. 既然要负载均衡,那么我们就需要启动多个 Provider 服务来构成集群,在启动前先对 Provider 改造一下,让它将端口号设置到商品标题上

    package com.zt.provider.controller;
    
    
    /**
     * Goods Controller 服务提供方
     */
    @RestController
    @RequestMapping("/goods")
    public class GoodsController {
    
        @Value("${server.port}")
        private int port;
    
        @Autowired
        private GoodsService goodsService;
    
        @GetMapping("/findOne/{id}")
        public Goods findOne(@PathVariable("id") int id){
    
            Goods goods = goodsService.findOne(id);
    
            goods.setTitle(goods.getTitle() + ":" + port);//将端口号,设置到商品标题上
            return goods;
        }
    }
    
    
  2. 接下来以多例启动 Provider,选择 edit configurations --> 勾选 allow parallel run

    在这里插入图片描述

    在这里插入图片描述

  3. 然后分别以 8001 和 8002 端口号分别启动 Provider

    在这里插入图片描述

  4. 启动 Consumer 进行测试

    http://localhost:9000/order/goods2/1
    

    采用轮询的方式,调用两个 8001 和 8002 两个 Provider

    {"id":1,"title":"华为手机:8001","price":3999.0,"count":10000}
    
    {"id":1,"title":"华为手机:8002","price":3999.0,"count":10000}
    

1.4 Ribbon 负载均衡策略

策略类命名描述
RandomRule随机策略随机选择server
RoundRobinRule轮询策略轮询选择, 轮询index,选择index对应位置的Server;
RetryRule重试策略对选定的负载均衡策略机上重试机制,在一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的server;
BestAvailableRule最低并发策略逐个考察server,如果server断路器打开,则忽略,再选择其中并发链接最低的server
AvailabilityFilteringRule可用过滤策略过滤掉一直失败并被标记为circuit tripped的server,过滤掉那些高并发链接的server(active connections超过配置的阈值)或者使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个Server的运行状态;
ResponseTimeWeightedRule响应时间加权重策略根据server的响应时间分配权重,响应时间越长,权重越低,被选择到的概率也就越低。响应时间越短,权重越高,被选中的概率越高,这个策略很贴切,综合了各种因素,比如:网络,磁盘,io等,都直接影响响应时间
ZoneAvoidanceRule区域权重策略综合判断server所在区域的性能,和server的可用性,轮询选择server并且判断一个AWS Zone的运行性能是否可用,剔除不可用的Zone中的所有server

设置负载均衡策略

  1. 编码方式

    在 Consumer 服务编写配置类,采用随即策略

    package com.zt.consumer.config;
    
    import com.netflix.loadbalancer.IRule;
    import com.netflix.loadbalancer.RandomRule;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MyRule {
        @Bean
        public IRule rule() {
           return new RandomRule();
        }
    }
    

    在启动类上设置给指定服务开启负载均衡策略,比如给 EUREKA-PROVIDER 开启策略 MyRule

    package com.zt.consumer;
    
    @SpringBootApplication
    @EnableEurekaClient
    @EnableDiscoveryClient
    /*
        配置Ribbon的负载均衡策略 name
        * name:设置 服务提供方的 应用名称
        * configuration:设置负载均衡Bean
     */
    @RibbonClient(name="EUREKA-PROVIDER",configuration = MyRule.class)
    public class ConsumerApp {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApp.class, args);
        }
    }
    
  2. 配置方式

    # 配置的方式设置Ribbon的负载均衡策略
    EUREKA-PROVIDER: # 设置的服务提供方的 应用名称
      ribbon:
        NFloadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 策略类
    
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bm1998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值