【微服务】2、一篇文章详解 Ribbon 负载均衡

news2024/11/21 1:30:30

Ribbon 负载均衡

  • 一、负载均衡原理(debug 源码)
    • (1) 基本介绍
    • (2) 打断点
      • ① LoadBalancerInterceptor.java - intercept()
      • ② RibbonLoadBalancerClient.java - execute()
      • ③ RibbonLoadBalancerClient.java - execute()
      • ④ RibbonLoadBalancerClient.java - getServer()
      • ⑤ ZoneAwareLoadBalancer.java - chooseServer()
      • ⑥ BaseLoadBalancer.java - chooseServer()
      • ⑦ RibbonLoadBalancerClient.java - execute()
    • (3) 流程
  • 二、负载均衡策略
    • (1) 负载均衡策略
    • (2) 调整负载均衡策略
      • ① 注入(@Bean)自己需要的负载均衡策略(IRule)
      • ② yaml 文件指定对某个指定微服务发送请求的使用采用指定的负载均衡策略
    • (3) 饥饿加载

📝 【上篇文章】
🔖 用 Eureka 做注册中心
🔖 user-service 的多个实例向 Eureka 注册中心注册自己的服务信息
🔖 order-service 通过服务名(如 userservice)获取 Eureka 注册中心里面指定服务名(如 userservice)的服务列表
🔖 通过一个服务名(如 userservice)可以获取到多个服务地址信息
❓ 究竟通过哪个地址信息发送请求呢 ❓
🔖 这通过【负载均衡】来决定

在这里插入图片描述

一、负载均衡原理(debug 源码)

(1) 基本介绍

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

📖 @LoadBalanced 注解表示:将来 RestTemplate 发起的请求要被 ribbon 拦截

在这里插入图片描述

📖 这个拦截操作是通过 LoadBalancerInterceptor 完成的
📖 它是 SpringCloud 中的拦截器org.springframework.cloud.client.loadbalancer
📖 LoadBalancerInterceptorClientHttpRequestInterceptor 接口的实现类


在这里插入图片描述
在这里插入图片描述

(2) 打断点

① LoadBalancerInterceptor.java - intercept()

在这里插入图片描述

在这里插入图片描述

public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
		final ClientHttpRequestExecution execution) throws IOException {
	// 获取请求地址
	final URI originalUri = request.getURI();
	// 获取主机名(微服务的服务名)
	String serviceName = originalUri.getHost();
	// 判断服务名是否为空
	Assert.state(serviceName != null,
			"Request URI does not contain a valid hostname: " + originalUri);
	// this.loadBalancer: RibbonLoadBalancerClient
	// 进入 this.loadBalancer.execute 方法
	return this.loadBalancer.execute(serviceName,
			this.requestFactory.createRequest(request, body, execution));
}

② RibbonLoadBalancerClient.java - execute()

public <T> T execute(String serviceId, LoadBalancerRequest<T> request)
		throws IOException {
	// serviceId: 服务名
	return execute(serviceId, request, null);
}

③ RibbonLoadBalancerClient.java - execute()

🔋 调用 RibbonLoadBalancerClient 重载的另一个 execute() 方法

public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
		throws IOException {
	// 通过服务名获取负载均衡器
	// loadBalancer 的 allServerList 中包含服务地址信息
	ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
	// 负载均衡, 获取某个服务地址信息
	Server server = getServer(loadBalancer, hint);
	if (server == null) {
		throw new IllegalStateException("No instances available for " + serviceId);
	}
	RibbonServer ribbonServer = new RibbonServer(serviceId, server,
			isSecure(server, serviceId),
			serverIntrospector(serviceId).getMetadata(server));

	return execute(serviceId, ribbonServer, request);
}

在这里插入图片描述
在这里插入图片描述

④ RibbonLoadBalancerClient.java - getServer()

protected Server getServer(ILoadBalancer loadBalancer, Object hint) {
	if (loadBalancer == null) {
		return null;
	}
	// Use 'default' on a null hint, or just pass it on?
	return loadBalancer.chooseServer(hint != null ? hint : "default");
}

⑤ ZoneAwareLoadBalancer.java - chooseServer()

🔋 调用父类的 chooseServer()

在这里插入图片描述

⑥ BaseLoadBalancer.java - chooseServer()

public Server chooseServer(Object key) {
    if (counter == null) {
        counter = createCounter();
    }
    counter.increment();
    // rule 默认是 ZoneAvoidanceRule 类型, 不为 null
    if (rule == null) {
        return null;
    } else {
        try {
            // 根据 key 选择一个活着的的服务
            return rule.choose(key);
        } catch (Exception e) {
            logger.warn("LoadBalancer [{}]:  Error choosing server for key {}", name, key, e);
            return null;
        }
    }
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

⑦ RibbonLoadBalancerClient.java - execute()

在这里插入图片描述

🔋 拿真实的服务地址替换服务名

(3) 流程

在这里插入图片描述

二、负载均衡策略

(1) 负载均衡策略

📝 Ribbon 的负载均衡策略是通过一个叫做 IRule 的接口来定义的,每个实现类是一种策略

在这里插入图片描述

在这里插入图片描述

(2) 调整负载均衡策略

📝 有种方式指定 IRule 实现,进而修改负载均衡规则

① 注入(@Bean)自己需要的负载均衡策略(IRule)

全局:整个微服务

  @Bean
  public IRule iRule() {
      return new RandomRule();
  }

📝 整个微服务发送的请求都通过【随机】方式负载均衡

② yaml 文件指定对某个指定微服务发送请求的使用采用指定的负载均衡策略

局部:只对某个微服务有作用

userservice: # 该微服务向 userservice 发送的请求使用【随机】负载均衡
  ribbon:
   NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

(3) 饥饿加载

📝 Ribbon 默认是采用懒加载 【第一次访问时才会创建LoadBalanceClient,请求时间会很长】
📝 饥饿加载会让 LoadBalanceClient 在项目启动时被创建,进而降低第一次访问的耗时

ribbon:
  eager-load:
    enabled: true # 开启饥饿加载
    clients:
      - userservice # 指定对哪些微服务进行饥饿加载

📖 根据 Bilibili 黑马程序员进行学习
📖 如有错误,请不吝赐教哦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/76730.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【STM32】详解RTC实时时钟的概念和配置示例代码

一、什么是RTC RTC(Real-time Clock)&#xff1a;实时时钟&#xff0c;本质上是一个支持BCD编码的定时器/计数器。主电源断电后能够由电池供电&#xff0c;使其时钟跳转依然正常。 二、STM32F4芯片内的RTC功能 ①日历时钟&#xff08;时分秒、年月日、星期&#xff09; ②两个闹…

六、排序算法介绍3

4、希尔排序 4.1 简单插入排序问题 简单的插入排序可能存在的问题&#xff0c;数组 arr { 2, 3, 4, 5, 6, 1 } 这时需要插入的数 1(最小)&#xff0c;简单插入排序的过程如下&#xff1a; {2,3,4,5,6,6} {2,3,4,5,5,6} {2,3,4,4,5,6} {2,3,3,4,5,6} {2,2,3,4,5,6} {1,2,3,4,…

CCIA技术沙龙 | “数据安全风险评估及安全服务实践” 沙龙成功举办

2022年12月8日&#xff0c;由中国网络安全产业联盟&#xff08;CCIA&#xff09;主办、CCIA数据安全工作委员会支持、杭州美创科技股份有限公司承办的“数据安全风险评估及数据安全服务实践”主题技术沙龙成功举办。 当前&#xff0c;我国数字经济快速发展、数字化转型持续深入…

Java对象深拷贝详解(List深拷贝)

1、Java中拷贝的概念 在Java语言中&#xff0c;拷贝一个对象时&#xff0c;有浅拷贝与深拷贝两种 浅拷贝&#xff1a;只拷贝源对象的地址&#xff0c;所以新对象与老对象共用一个地址&#xff0c;当该地址变化时&#xff0c;两个对象也会随之改变。 深拷贝&#xff1a;拷贝对…

一起学习用Verilog在FPGA上实现CNN----(一)总体概述

1 总体概述 为避免闭门造车&#xff0c;找一个不错的开源项目&#xff0c;学习在FPGA上实现CNN&#xff0c;为后续的开发奠定基础 1.1 项目链接 大佬的开源项目链接&#xff1a; CNN-FPGA 链接跳转界面如下&#xff1a; 大佬的该项目已经发表论文&#xff0c;而且开源工程结…

Qt5.6.1移植海思Hi3521d(一)

系列文章目录 文章目录系列文章目录前言一、开发环境二、搭建环境1.准备2.海思SDK和交叉编译器安装2.测试交叉编译器一下3.安装tftp总结前言 上半年做个一个Qt移植海思芯片的程序&#xff0c;感觉差不多快忘记了&#xff0c;赶紧记录一下 一、开发环境 系统&#xff1a;Ubunt…

初学Python到月入过万最快的兼职途径(纯干货)

程序员小猴紫&#xff0c;不错过任何一次干赚钱干货 1.兼职薪资&#xff0c;附行哥工资单2.兼职门槛&#xff0c;附学习知识清单3.兼职途径&#xff0c;附入职考核过程4.我的兼职感受 答应小猴紫的第一篇赚钱干货推文来啦&#xff0c;行哥第一个在读书期间通过兼职赚到的10w收…

Web前端大作业—里约热内卢奥运会(html+css+javascript)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

产品经理 - 产品设计方法论需求分析部分

整体 – 产品设计方法论思维导图 个人整理&#xff0c;存在异议大家可以讨论下 需求分析方法论 需求分析为需求收集的延展&#xff0c;需求收集后即需进行需求分析&#xff0c;拆解需求后方可业务落地&#xff0c;此处我将其分为两步&#xff0c;一是主动发散型需求分析&am…

移动端项目(第十九课)Vite+Vant组件环境配置

常用到的环境配置时不我待(第十八课)项目环境搭建_星辰镜的博客-CSDN博客 在上面的环境的基础上加上下面的一下配置 Normalize.css: Make browsers render all elements more consistently. (necolas.github.io) 介绍 | Pinia 中文文档 (web3doc.top) Day.js 中文文档 - 2kB 大…

【Java版oj】day02排列子序列

目录 一、原题再现 二、问题分析 三、完整代码 一、原题再现 链接&#xff1a;排序子序列_牛客笔试题_牛客网 来源&#xff1a;牛客网 [编程题]排序子序列 热度指数&#xff1a;10105 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 32M&…

水果店引流活动推荐_分享水果店微信小程序制作步骤

试试做个小程序拯救你的店&#xff01;让你做出有效果的活动&#xff0c;每笔钱都花在刀刃上&#xff01; 第一&#xff0c;提升水果销量&#xff0c;降低损耗 用水果店小程序做拼团、砍价、秒杀活动&#xff0c;并讲原本卖不完的水果&#xff0c;做成果盘吸引客人注册会员。上…

Manufactoria介绍及各关卡解法

Manufactoria解法Manufactoria基本介绍解法RobotoastRoboManufactoria基本介绍 Manufactoria是一个以制造工厂为背景的程序设计游戏。在游戏中&#xff0c;玩家需要在有限的平面空间中巧妙地排布传送带&#xff0c;打点器与分支器&#xff0c;完成识别或改写特定模式的字符串的…

6.AOP之转账案例

数据准备 CREATE TABLE account (id int(11) NOT NULL,name varchar(100) NOT NULL,money decimal(7,2) NOT NULL,create_time datetime(6) NOT NULL,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8;insert into account values(1,"steven",10000,"2022…

循环程序设计 乘法口诀表

凡是写循环程序 必须满足两个条件 一是存在相同的操作 二是有规律 对于乘法口诀表 我们都很熟悉 如下图是左下角的 探求一下 规律&#xff1a; 1 多个乘法 2 规律性 第一1行 1个乘法运算 1*1 第二2行 2个乘法运算 1*2 2*2 第三3行 3个乘法运算 1*3 2*3 3*3 第四4行 4个…

关于Linux的基础总结

关于Linux的基础总结 文章目录关于Linux的基础总结前言一、为什么Linux如此流行&#xff1f;1.原因2.Linux系统的版本二、Linux的基础命令1.目录结构2.文件命令1.ls2.pwd3.cd4.touch、mkdir5.cat、tail、head、tail、od、tee、more、less6.rm、cp、mv7.find、grep、xargs8.tar、…

voc To yolov5-6.1数据集格式转换

voc To yolov5-6.1数据集格式转换 已有的数据集操作第一步:划分训练集、验证集、测试集通过脚本文件(createImageSet.py)生成训练集和验证集本代码需要修改的地方:结果:第二步:vocToyolo1、Head_classes.json文件:Head_classes.json文件对应的代码:3、操作技巧:2、第二…

用Python画一个足球

文章目录前情提要先画六边形再画五边形前情提要 如果想优雅地绘制一个足球&#xff0c;那首先需要绘制正二十面体&#xff1a;用Python绘制正二十面体 其核心代码为 import numpy as np from itertools import product G (np.sqrt(5)-1)/2 def getVertex():pt2 [(a,b) fo…

【Flask框架】——07 request请求和 get请求 post请求

request参数 指定请求方式 在Flask中&#xff0c;可以定义路由默认的请求方式&#xff1a; 利用 methods 参数可以自己指定一个接口的请求方式 get方式&#xff1a;把请求参数放到为url的&#xff1f;后面&#xff0c;每个请求参数格式为&#xff1a;参数名参数值。参数之间…

全梯度下降算法、随机梯度下降算法、小批量梯度下降算法、随机平均梯度下降算法、梯度下降算法总结

一、常见梯度下降算法 全梯度下降算法(Full gradient descent&#xff0c;FGD&#xff09;随机梯度下降算法&#xff08;Stochastic gradient descent&#xff0c;SGD&#xff09;随机平均梯度下降算法&#xff08;Stochastic average gradient descent&#xff0c;SAGD&#…