四、ribbon

负载均衡(Load Balancer,简称LB):其含义就是指将负载(客户端发送的请求、工作任务等)进行平衡、分摊到多个服务上处理,从而协同完成工作任务。

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具,它将提供一系列完整的配置项如:连接超时、重试等等,简单的说,就是在配置文件中列出LB后面所有的机器,Ribbon会自动基于某种规则(如简单轮询、随即连接等等)去连接这些机器。我们也可以更容易使用Ribbon实现自定义的负载均衡算法

  • ribbon作用:

    • 将可用的服务列表返回给客户端
    • 核心:将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)
  • 常用的负载均衡软件有Nginx、Lvs等

  • dubbo、Spring Cloud中均提供了负载均衡,Spring Cloud的负载均衡算法可以自定义

  • 负载均衡简单分类

    • 集中式LB

      即在服务的消费方和提供方之间使用独立的LB设施,如Nginx(反向代理服务器),由该设施负责把访问请求通过某种策略转发至服务提供方

    • 进程式LB

      将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可以用,然后自己再从这些地址中选出一个合适的服务器

      Ribbon属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址

4.1 Ribbon使用(单服务提供者)

  • 在相应的消费者module中添加依赖

    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-ribbon</artifactId><version>1.4.6.RELEASE</version>
    </dependency>
    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version>
    </dependency>
    
  • 编写客户端配置文件

    # Eureka 配置
    eureka:client:register-with-eureka: false # 不向Eureka注册自己,消费者只需要去注册中心拿服务service-url:# 客户端可以从以下三个注册中心中随机选择一个,取出服务defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  • 在主启动类中添加开启Eureka注解

    @EnableEurekaClient
    
  • 在configBean中添加负载均衡注解

    // 配置实现负载均衡的RestTemplate
    @Bean
    @LoadBalanced // Ribbon
    public RestTemplate getRestTemplate() {return new RestTemplate();
    }
    

    **注意:**使用了Ribbon做负载均衡,此时消费者请求的url应该是一个变量,变量名为需要调用的服务的名称(即注册中心所显示的服务名,本例中服务只有一个,为SPRINGCLOUD-PROVIDER-DEPT),因此需要对消费者的controller层做出改变,将原来的http://localhost:8001更换成对应的服务名

     // private static final String REST_URL_PREFIX = "http://localhost:8001";// 使用Ribbon做负载均衡时,消费者请求的地址应该是一个变量,该变量即服务的名称private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
    

启动注册中心、服务提供者、消费者,在注册中心可以看到服务已注册

消费者可成功调用服务

结论:Ribbon和Eureka整合以后,客户端可以直接调用服务,不用关心注册中心的端口号和IP地址

4.2 Ribbon使用(多服务提供者)

  • 创建三个不同的数据库db01、db02、db03

  • 复制得到另外两个服务提供者8002、8003,服务提供者的功能均相同,且服务名称也相同(名称在如下yml文件中进行配置)

    spring:application:name: springcloud-provider-dept
    
  • 启动3个服务提供者、两个注册中心、一个消费者

消费者每次发出请求localhost:81/consumer/dept/list,都会调用到不同的数据库,由于默认采用轮询的负载均衡方式,因此调用顺序为db01、db02、db03

4.3 自定义负载均衡策略

与springcloud包同级的位置建立配置包myrule,以建立自定义Ribbon类,并在启动类中添加注解@RibbonClient,configuration = MyRule.class表示在微服务启动的时候,会加载自定义的Ribbon类

package com.mark.springcloud;/** @project: springcloud* @name: DeptConsumer_80* @author: Mark* @Date: 2021/7/22* @Time: 23:00*/import com.mark.myrule.MyRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;@SpringBootApplication
@EnableEurekaClient
// 对名称为SPRINGCLOUD-PROVIDER-DEPT的服务进行均衡
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT", configuration = MyRule.class)
public class DeptConsumer_81 {public static void main(String[] args) {SpringApplication.run(DeptConsumer_81.class, args);}
}

在myrule包下新建自定义配置类、负载均衡策略类

配置类

package com.mark.myrule;/** @project: springcloud* @name: MyRule* @author: Mark* @Date: 2021/7/24* @Time: 21:03*/import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyRule {@Beanpublic IRule myRandomRule() {return new MarkRandomRule(); // 默认为轮询,现自定义为MarkRandomRule()}
}

负载均衡策略类(这一程序主要是从自带的均衡算法RandomRule()更改得来)

package com.mark.myrule;/** @project: springcloud* @name: MarkRandomRule* @author: Mark* @Date: 2021/7/24* @Time: 21:21*/import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;import java.util.List;
import java.util.concurrent.ThreadLocalRandom;public class MarkRandomRule extends AbstractLoadBalancerRule {// 每个服务,访问5次,5次后换下一个服务,总共3个服务private int total = 0; // 被调用的次数private int currentIndex = 0; // 当前是谁在提供服务//    @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")public Server choose(ILoadBalancer lb, Object key) {if (lb == null) {return null;}Server server = null;while (server == null) {if (Thread.interrupted()) {return null;}List<Server> upList = lb.getReachableServers(); // 获取活着的服务List<Server> allList = lb.getAllServers(); // 获取所有服务int serverCount = allList.size();if (serverCount == 0) {return null;}//            int index = chooseRandomInt(serverCount); // 生存区间随机数
//            server = upList.get(index); // 从活着的服务中随机获取一个// ==========================================if (total < 5) {server = upList.get(currentIndex); // 从活着的服务中,获取指定的服务total++;} else {total = 0;currentIndex++;if (currentIndex > upList.size()) { // 如果服务索引大于了活服务的数量currentIndex = 0; // 重新从第一个服务开始调用}server = upList.get(currentIndex);}// ==========================================if (server == null) {Thread.yield();continue;}if (server.isAlive()) {return (server);}server = null;Thread.yield();}return server;}protected int chooseRandomInt(int serverCount) {return ThreadLocalRandom.current().nextInt(serverCount);}@Overridepublic Server choose(Object key) {return choose(getLoadBalancer(), key);}@Overridepublic void initWithNiwsConfig(IClientConfig clientConfig) {// TODO Auto-generated method stub}
}

访问路径 http://localhost:81/consumer/dept/list 可成功调用服务,并且当访问同一服务的次数大于5次后,将切换服务,与自定义负载均衡策略相符

前5次访问的结果

第6次的访问结果

Spring Cloud学习笔记(三)相关推荐

  1. Spring Cloud 学习笔记(三) 之服务治理模块Spring Cloud 服务发现与消费

    2019独角兽企业重金招聘Python工程师标准>>> 一.前言 前面的文章我们已经讲了如何搭建服务注册中心,如何搭建客户端去注册.接下来我们讲一下服务的发现与消费 二.服务注册 1 ...

  2. Spring Cloud 学习笔记(2 / 3)

    Spring Cloud 学习笔记(1 / 3) Spring Cloud 学习笔记(3 / 3) - - - 56_Hystrix之全局服务降级DefaultProperties 57_Hystri ...

  3. Spring Cloud 学习笔记(2 3)

    Spring Cloud 学习笔记(1 / 3) Spring Cloud 学习笔记(3 / 3) - - - 56_Hystrix之全局服务降级DefaultProperties 57_Hystri ...

  4. Spring Cloud 学习笔记(1 / 3)

    Spring Cloud 学习笔记(2 / 3) Spring Cloud 学习笔记(3 / 3) - - - 01_前言闲聊和课程说明 02_零基础微服务架构理论入门 03_第二季Boot和Clou ...

  5. Spring Cloud学习笔记

    Spring Cloud学习笔记 相关代码地址:https://github.com/gongxings/spring-cloud-study.git 一.工程环境搭建 spring cloud版本: ...

  6. Spring Cloud学习笔记【十二】Hystrix的使用和了解

    Spring Cloud学习笔记[十二]Hystrix的使用和了解 Hystrix [hɪst'rɪks],中文含义是豪猪,因其背上长满棘刺,从而拥有了自我保护的能力.本文所说的Hystrix是Net ...

  7. Spring Cloud 学习笔记(3 3)

    Spring Cloud 学习笔记(1 / 3) Spring Cloud 学习笔记(2 / 3) - - - 108_Nacos之Linux版本安装 109_Nacos集群配置(上) 110_Nac ...

  8. Spring Cloud 学习笔记(3 / 3)

    Spring Cloud 学习笔记(1 / 3) Spring Cloud 学习笔记(2 / 3) - - - 108_Nacos之Linux版本安装 109_Nacos集群配置(上) 110_Nac ...

  9. Spring Cloud 学习笔记(四)-Spring Cloud Hystrix

    Spring Cloud 学习笔记(四)-Spring Cloud Hystrix 由于前一阵子项目的原因,今天才继续弄上,今天想学习一下Hystrix组件 这个组件还挺抽象的,最开始我一直没太明白, ...

  10. Spring Cloud学习笔记—网关Spring Cloud Gateway官网教程实操练习

    Spring Cloud学习笔记-网关Spring Cloud Gateway官网教程实操练习 1.Spring Cloud Gateway介绍 2.在Spring Tool Suite4或者IDEA ...

最新文章

  1. 注意力机制取代卷积网络,预测准确性提升超30%
  2. Hyperledger Fabric 核心模块(6)configtxlator工具
  3. boost::fusion::front_extended_deque用法的测试程序
  4. 神经网络与深度学习——TensorFlow2.0实战(笔记)(二)(安装TensorFlow2.0)
  5. Storm集群开启HA高可用
  6. [php]php设计模式 Facade(外观模式)
  7. 解决Sql中DIstinct与Order By共同使用的冲突问题
  8. 09-js数组常用方法
  9. php js多语言切换,php简单实现多语言切换的方法_php技巧
  10. 嵌套查询(2020-3-25 )
  11. day14:磁盘管理df/du/fdisk/parted命令
  12. 【毕业设计/课程设计】基于STM32的六臂行走机器小车设计
  13. 【Python】基于Python的百度迁徙1——迁入、迁出数据(附代码)
  14. hping 详解_hping3使用
  15. 关于W5500/LAN8720与STM32以及与千兆交换机芯片通信的硬件、软件调试不通的问题
  16. 2022最新手机号码正则
  17. React 父组件获取子组件的方法/数据(useRef
  18. find7刷Android,OPPO Find 7刷Color OS 2.0教程
  19. git强制拉取最新代码
  20. DINO:一种新的端到端目标检测器(速读版)

热门文章

  1. oracle会话临时表会造成死锁,Oracle Temporary Tables(Oracle 临时表)
  2. 如何用水经注万能地图下载器进行投影转换
  3. [转]什么样的女人才是老婆
  4. 自动切换背景的登录页面
  5. ISE网表逆向分析与使用技巧
  6. RPG Maker MV游戏解包
  7. WebQQ桌面化替代方案
  8. js 验证身份证号码正确性
  9. Sqlserver2000数据备份怎么导入到Sqlserver2008
  10. Android中关于空指针异常的解决办法