行业资讯 2025年08月6日
0 收藏 0 点赞 885 浏览 3054 个字
摘要 :

文章目录 一、环境准备 二、架构说明 三、Ribbon配置 四、RestTemplate 五、Ribbon负载均衡策略 六、如何替换Ribbon负载均衡策略 第1步:新建自定义规则包 第2步:自定……




  • 一、环境准备
  • 二、架构说明
  • 三、Ribbon配置
  • 四、RestTemplate
  • 五、Ribbon负载均衡策略
  • 六、如何替换Ribbon负载均衡策略
    • 第1步:新建自定义规则包
    • 第2步:自定义规则类
    • 第3步:修改主启动类
    • 第4步:测试
  • 七、Ribbon轮询策略原理

一、环境准备

为了实现Ribbon负载均衡的演示,我们首先将项目恢复到我们第12小节的状态,即:我们有

  • 1个服务消费者:cloud-consumer-order80
  • 2个服务提供者:cloud-provider-payment8001cloud-provider-payment8002
  • 3个服务注册中心:cloud-eureka-server7001、cloud-eureka-server7002cloud-eureka-server7003

二、架构说明

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

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

三、Ribbon配置

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

<dependency>
    <groupId>com.netflix.ribbon</groupId>
    <artifactId>ribbon</artifactId>
    <version>2.2.2</version>
</dependency>

四、RestTemplate

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

@GetMapping("/consumer/payment/getForEntity/{id}")
    public CommonResult<Payment> getPayment2(@PathVariable("id") Long id){
        ResponseEntity<CommonResult> 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<Payment> create2(Payment payment){
        ResponseEntity<CommonResult> entity = restTemplate.postForEntity(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
        if(entity.getStatusCode().is2xxSuccessful()){
            return entity.getBody();
        }else{
            return new CommonResult(444,"新增失败");
        }
    }

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

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

五、Ribbon负载均衡策略

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

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

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

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

修改cloud-consumer-order80代码,新建com.panziye.myrule

官方文档明确给出了警告:
这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的了。
而我们的主启动类上的@SpringBootApplication注解源码上就带有@ComponentScan注解,因此我们自定义的规则包,不能与主启动类在同一个包下。

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注解:

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

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

第4步:测试

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

七、Ribbon轮询策略原理

1)Ribbon轮询策略原理:

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

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

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/7811.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号