当前位置: 首页 > news >正文

SpringCloud(三) Ribbon负载均衡

SpringCloud(二) Eureka注册中心的使用-CSDN博客

在SpringCloud(二)中学习了如何通过Eureka实现服务的注册和发送,从而通过RestTemplate实现不同微服务之间的调用,加上@LoadBalance注解之后实现负载均衡,那负载均衡的原理是什么呢?

目录

一, 负载均衡

1.1 负载均衡原理

 1.2 源码追踪

1, LoadBalanceInterceptor

2, LoadBalanceClient

3, 负载均衡策略 

1.3 总结负载均衡 

二, 代码示例

三, 负载均衡策略

3.1 负载均衡策略

3.2 自定义负载均衡策略

四, 负载均衡


一, 负载均衡

1.1 负载均衡原理

SpringCloud底层其实是利用了一个名为Ribbon的组件来实现负载均衡功能的.

此时就可以将我们发出的http://userservice/user/1请求变成http://localhost:8081

 1.2 源码追踪

为什么我们只输入了user-service的服务名称就可以访问了呢?

显然有人帮我们根据service名称,获取到了实例的ip和端口号,它就是LoadBalanceInterceptor,这个类会对RestTemplate的请求进行拦截,然后从Eureka根据服务id获取服务列表,随后利用负载均衡算法得到真是的服务地址信息,替换服务id.

1, LoadBalanceInterceptor

可以看到这里的intercept方法,拦截了用户大的HttpRequest请求,然后做了以下几件事:

  • request.getURI():获取请求uri,本例中就是http://userservice/user/1
  • originalUri.getHost():获取uri路径的主机名,其实就是服务id,user-service
  • this.loadBalancer.execute():处理服务id,和用户请求

2, LoadBalanceClient

继续跟入execute方法:

  • getLoadBalancer(serviceId):根据服务id获取ILoadBalancer,而ILoadBalancer会拿着服务id去eureka中获取服务列表并保存起来
  • getServer(loadBalancer):利用内置的负载均衡算法,从服务列表中选择一个

放行后,再次访问并跟踪,发现获取的是8081:

3, 负载均衡策略 

在刚才的代码中,可以看到获取服务是通过一个getServer方法来做负载均衡:

继续跟入:

 继续跟踪源码chooseServer方法,发现这么一段代码:

 看看这个rule是谁:

这里的rule默认值是一个RoundRobinRule,看类的介绍(意思是轮询):

1.3 总结负载均衡 

SpringCloudRibbon的底层采用了一个拦截器,拦截了RestTemplate发出的请求,对地址进行了修改,用一幅图总结一下:

基本流程如下:

  •  拦截我们的RestTemplate请求http://userservice/user/1;
  • RibbonLoadBalancerClient会从请求url中获取服务名称,也就是userservice;
  • DynamicServerListBalance根据userservice到eureka拉取服务列表;
  • eureka返回列表,localhots:8081和localhost:8082;
  • IRule利用内置负载均衡规则,从列表中选择一个,例如localhost:8081;
  • RibbonLoadBalanceClient修改请求地址,用localhost:8081代替userservice,得到http://localhost:8081/user/1.

二, 代码示例

现在我们有两个user-service微服务,使用order-service多次调用user-service查看服务落在两个user-service的频率

启动服务并清空两个user-service服务的日志:

 在浏览器多次调用order-service中的queryOrderByUserId接口:

分别查看两个user-service的日志打印结果:

user-service1:

user-service2:

从日志结果可以看出,在不改变负载均衡策略的情况下,默认的策略是轮询的方式.

三, 负载均衡策略

3.1 负载均衡策略

负载均衡的规则都定义在IRule接口中,而IRule有很多不同的实现类:

不同规则的含义如下:

内置负载均衡规则类规则描述
RoundRobinRule简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。
AvailabilityFilteringRule对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。 (2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的<clientName>.<clientConfigNameSpace>.ActiveConnectionsLimit属性进行配置。
WeightedResponseTimeRule为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。
ZoneAvoidanceRule以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。
BestAvailableRule忽略那些短路的服务器,并选择并发数较低的服务器。
RandomRule随机选择一个可用的服务器。
RetryRule重试机制的选择逻辑。

默认的实现就是ZoneAvoidanceRule,是一种轮询方案.

3.2 自定义负载均衡策略

通过定义IRule实现可以修改负载均衡规则,有两种方式:

1. 代码方式:在order-service中的OrderApplication类中,定义一个新的IRule:

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

2. 配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改规则:

userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则 

一般用默认的负载均衡规则,不做修改.

四, 负载均衡

Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长.

而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:

ribbon:eager-load:enabled: trueclients: userservice

未开启饥饿加载时:

第一次访问的时候耗时是579ms

开启饥饿加载时:

先在配置文件里进行配置

 重启order-service进行访问

可以看出开启饥饿加载后第一次访问的时间变少了很多,未232ms.

 

相关文章:

SpringCloud(三) Ribbon负载均衡

SpringCloud(二) Eureka注册中心的使用-CSDN博客 在SpringCloud(二)中学习了如何通过Eureka实现服务的注册和发送,从而通过RestTemplate实现不同微服务之间的调用,加上LoadBalance注解之后实现负载均衡,那负载均衡的原理是什么呢? 目录 一, 负载均衡 1.1 负载均衡原理 1.2 源…...

vue2:路由前置守卫无法获取到this.$store.state.xxx

在获取到vuex的数据时候&#xff0c;想在router目录下的index.js文件去获取到vuex仓库中声明的全局变量&#xff0c;但是通过this.$store.stote.xxx去获取的时候&#xff0c;报错提示&#xff1a;$store未定义 一、store/index.js const store new Vuex.Store({state: {// 属…...

Unity的碰撞检测(五)

温馨提示&#xff1a;本文基于前一篇“Unity的碰撞检测(四)​​​​​​​”继续探讨两个游戏对象具备刚体的BodyType均为Dynamic&#xff0c;但是Collision Detection属性不同的碰撞检测&#xff0c;阅读本文则默认已阅读前文。 &#xff08;一&#xff09;测试说明 在基于两…...

Flutter笔记:Flutter的应用生命周期状态(lifecycleState)管理

Flutter笔记 Flutter的应用生命周期状态&#xff08;lifecycleState&#xff09;管理 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/…...

代碼隨想錄算法訓練營|第五十四天|300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组。刷题心得(c++)

讀題 300.最长递增子序列 看完代码随想录之后的想法 思想上很簡單&#xff0c;dp[i]表示i之前的包括i的numbers[i]節尾的最長上升子序列的長度 並且透過兩層迴圈&#xff0c;一層遍歷全部&#xff0c;一層遍歷到i&#xff0c;透過比較當前dp[i]還是dp[j] 1哪個比較大&…...

正点原子嵌入式linux驱动开发——Linux 串口RS232/485/GPS 驱动

串口是很常用的一个外设&#xff0c;在Linux下通常通过串口和其他设备或传感器进行通信&#xff0c;根据 电平的不同&#xff0c;串口分为TTL和RS232。不管是什么样的接口电平&#xff0c;其驱动程序都是一样的&#xff0c;通过外接RS485这样的芯片就可以将串口转换为RS485信号…...

HDFS工作流程和机制

HDFS写数据流程&#xff08;上传文件&#xff09; 核心概念--Pipeline管道 HDFS在上传文件写数据过程中采用的一种传输方式。 线性传输&#xff1a;客户端将数据写入第一个数据节点&#xff0c;第一个数据节点保存数据之后再将快复制到第二个节点&#xff0c;第二节点复制给…...

CMMI/ASPICE认证咨询及工具服务

服务概述 质量专家戴明博士的名言“如果你不能描述做事情的过程&#xff0c;那么你不知道你在做什么”。过程是连接有能力的工程师和先进技术的纽带&#xff0c;因此产品开发过程直接决定了产品的质量和研发的效率。 经纬恒润可结合多体系要求&#xff0c;如IATF16949\ISO26262…...

【NI-DAQmx入门】计数器

1.计数器的作用 NI产品的计数器一般来说兼容TTL信号&#xff0c;定义如下&#xff1a;0-0.8V为逻辑低电平&#xff0c;2~5V为高电平&#xff0c;0.8-2V为高阻态&#xff0c;最大上升下降时间为50ns。 计数器可以感测上升沿&#xff08;从逻辑低到逻辑高的转变&#xff09;和下降…...

Python爬取读书网的图片链接和书名并保存在数据库中

一个比较基础且常见的爬虫&#xff0c;写下来用于记录和巩固相关知识。 一、前置条件 本项目采用scrapy框架进行爬取&#xff0c;需要提前安装 pip install scrapy# 国内镜像 pip install scrapy -i https://pypi.douban.com/simple 由于需要保存数据到数据库&#xff0c;因…...

js解决加油站

在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定两个整数数组 gas 和 cost &…...

【c++|opencv】二、灰度变换和空间滤波---5.中值滤波

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 1. 中值滤波 #include<iostream> #include<opencv2/opencv.hpp> #include"Salt.h"using namespace cv; using namespace std;voi…...

python之pytorch多进程

目录 1、创建并运行并行进程 2、使用队列&#xff08;Queue&#xff09;来共享数据 3、进程池 4、进程锁 5、比较使用多进程和使用单进程执行一段代码的时间消耗 6、共享变量 多进程是计算机科学中的一个术语&#xff0c;它是指同时运行多个进程&#xff0c;这些进程可以…...

sqoop 抽数报错com.mysql.cj.exceptions.WrongArgumentException: HOUR_OF_DAY: 2 -> 3

文章目录 1.sqoop 抽数报错: Caused by: com.mysql.cj.exceptions.WrongArgumentException: HOUR_OF_DAY: 2 -> 3 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructor…...

【Acwing170】加成序列(dfs+迭代加深+剪枝)题解和一点感想

本思路来自acwing算法提高课 题目描述 看本文需要准备的知识 1.dfs算法基本思想 2.对剪枝这个词有个简单的认识 迭代加深思想和此题分析 首先&#xff0c;什么是迭代加深呢&#xff1f;当一个问题的解有很大概率出现在递归树很浅的层&#xff0c;但是这个问题的解本身存在…...

Android开发知识学习——Kotlin进阶

文章目录 次级构造主构造器init 代码块构造属性data class相等性解构Elvis 操作符when 操作符operatorLambdainfix 函数嵌套函数注解使用处目标函数简化函数参数默认值扩展函数类型内联函数部分禁用用内联具体化的类型参数抽象属性委托属性委托类委托 Kotlin 标准函数课后题 次…...

iOS使用AVCaptureSession实现音视频采集

AVCaptureSession配置采集行为并协调从输入设备到采集输出的数据流。要执行实时音视频采集&#xff0c;需要实例化采集会话并添加适当的输入和输出。 AVCaptureSession&#xff1a;管理输入输出音视频流AVCaptureDevice&#xff1a;相机硬件的接口&#xff0c;用于控制硬件特性…...

springboot和flask整合nacos,使用openfeign实现服务调用,使用gateway实现网关的搭建(附带jwt续约的实现)

环境准备&#xff1a; 插件版本jdk21springboot 3.0.11 springcloud 2022.0.4 springcloudalibaba 2022.0.0.0 nacos2.2.3&#xff08;稳定版&#xff09;python3.8 nacos部署&#xff08;docker&#xff09; 先创建目录&#xff0c;分别创建config&#xff0c;logs&#xf…...

深入浅出排序算法之基数排序

目录 1. 前言 1.1 什么是基数排序⭐⭐⭐ 1.2 执行流程⭐⭐⭐⭐⭐ 2. 代码实现⭐⭐⭐ 3. 性能分析⭐⭐ 3.1 时间复杂度 3.2 空间复杂度 1. 前言 一个算法&#xff0c;只有理解算法的思路才是真正地认识该算法&#xff0c;不能单纯记住某个算法的实现代码&#xff01; 1.…...

CSS选择器、CSS属性相关

CSS选择器 CSS属性选择器 通过标签的属性来查找标签&#xff0c;标签都有属性 <div class"c1" id"d1"></div>id值和class值是每个标签都自带的属性&#xff0c;还有另外一种&#xff1a;自定义属性 <div class"c1" id"d1&…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

数据库——redis

一、Redis 介绍 1. 概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的内存键值数据库系统&#xff0c;具有以下核心特点&#xff1a; 内存存储架构&#xff1a;数据主要存储在内存中&#xff0c;提供微秒级的读写响应 多数据结构支持&…...