Ribbon实现负载均衡—SpringCloud(H版)微服务学习教程(20)

IT 文章5年前 (2021)发布 小编
0 0 0

一、环境准备

为了实现Ribbon负载均衡的演示,我们首先将项目恢复到我们第12小节的状态,即:我们有
[list]1个服务消费者:cloud-consumer-order80
2个服务提供者:cloud-provider-payment8001cloud-provider-payment8002
3个服务注册中心:cloud-eureka-server7001、cloud-eureka-server7002cloud-eureka-server7003[/list]

二、架构说明

Ribbon在工作时分成两步:
1)第一步先选择Eureka Server ,它优先选择在同一个区域内负载较少的server。
2)第二步再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址 。
其中Ribbon提供了多种策略:比如轮询、随机和根据响应时间加权。

Ribbon实现负载均衡—SpringCloud(H版)微服务学习教程(20)
总结: Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例。

ad

程序员导航

优网导航旗下整合全网优质开发资源,一站式IT编程学习与工具大全网站

三、Ribbon配置

我们在之前的项目中,就已经可以实现负载均衡了,但是我们在pom里确并没有发现导入Ribbon的相关依赖,这是为什么?原因就在于在我们导入的Eureka Client依赖中已经包含了Ribbon相关依赖,如图:
Ribbon实现负载均衡—SpringCloud(H版)微服务学习教程(20)
如果是没有整合Ribbon依赖的需要单独引入Ribbon,其GAV坐标为:


    com.netflix.ribbon
    ribbon
    2.2.2

四、RestTemplate

我们之前在Order80OrderController中都是使用的RestTemplategetForObject/postForObject方法,现在我们再新增两个方法,使用下getForEntity/postForEntity方法。

@GetMapping("/consumer/payment/getForEntity/{id}")
    public CommonResult getPayment2(@PathVariable("id") Long id){
        ResponseEntity entity = restTemplate.getForEntity(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
        log.info(entity.getStatusCode()+"\t"+entity.getHeaders());
        if(entity.getStatusCode().is2xxSuccessful()){
            return entity.getBody();
        }else{
            return new CommonResult(444,"查询失败");
        }
    }

    @GetMapping("/consumer/payment/postForEntity")
    public CommonResult create2(Payment payment){
        ResponseEntity entity = restTemplate.postForEntity(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
        if(entity.getStatusCode().is2xxSuccessful()){
            return entity.getBody();
        }else{
            return new CommonResult(444,"新增失败");
        }
    }

[v_blue]区别:
getForObjectpostForObject 返回对象为响应体中数据转化成的对象,基本上可以理解为Json
getForEntitypostForEntity 返回对象为ResponseEntity对象, 包含了响应中的- -些重要信息,比如响应头、响应状态码、响应体等[/v_blue]

接下来测试get和create发现正常使用,在此不再赘述

ad

AI 工具导航

优网导航旗下AI工具导航,精选全球千款优质 AI 工具集

五、Ribbon负载均衡策略

Ribbon作为后端负载均衡器,比Nginx更注重的是承担并发而不是请求分发,可以直接感知后台动态变化来指定分发策略。它一共提供了7种负载均衡策略,均是IRule接口的实现类,IRule的继承实现图如下:
Ribbon实现负载均衡—SpringCloud(H版)微服务学习教程(20)
其提供的7中负载均衡实现类及说明如下:
Ribbon实现负载均衡—SpringCloud(H版)微服务学习教程(20)

六、如何替换Ribbon负载均衡策略

这里我们以将原来默认的轮询策略替换为随机策略为例:

第1步:新建自定义规则包

修改cloud-consumer-order80代码,新建com.panziye.myrule
[v_warn]官方文档明确给出了警告:
这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的了。
而我们的主启动类上的@SpringBootApplication注解源码上就带有@ComponentScan注解,因此我们自定义的规则包,不能与主启动类在同一个包下。[/v_warn]
Ribbon实现负载均衡—SpringCloud(H版)微服务学习教程(20)

第2步:自定义规则类

我们在myrule包下新建名为MyRibbonRule规则类(这里我们使用注解配置的方式实现):

package com.panziye.myrule;

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 MyRibbonRule {
    @Bean
    public IRule MyRibbonRule(){
        // 使用随机策略
        return new RandomRule();
    }
}

目前项目结构如下:
Ribbon实现负载均衡—SpringCloud(H版)微服务学习教程(20)

第3步:修改主启动类

我们需要在主启动类OrderMain80上新增@RibbonClient注解:

ad

免费在线工具导航

优网导航旗下整合全网优质免费、免注册的在线工具导航大全

@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MyRibbonRule.class)

[v_blue]提示:name指定服务应用名,configuration 指定自定义规则类[/v_blue]

第4步:测试

启动着5个模块(注意先后顺序),测试查看访问策略确实变成了随机,在此不再演示。

七、Ribbon轮询策略原理

1)Ribbon轮询策略原理:

rest接口第几次请求数%服务器集群总数量=实际调用服务器位置下标,每次服务 重启动后rest接口计数从1开始

Ribbon实现负载均衡—SpringCloud(H版)微服务学习教程(20)
2)源码
我们可以通过ctrl+n搜索IRule,查看IRule相关源码,再ctrl+h查看其实现类,我们这里查看RoundRobinRule,这里面涉及到自旋锁、CAS算法等知识(JUC),有兴趣的可自行探究。
3)手写负载均衡算法,有兴趣可自行学习

© 版权声明

相关文章

暂无评论

暂无评论...