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

SpringCloud - 新版淘汰 Ribbon,在 OpenFeign 中整合 LoadBalancer 负载均衡

目录

一、LoadBalancer 负载均衡

1.1、前言

1.2、LoadBalancer 负载均衡底层实现原理

二、整合 OpenFeign + LoadBalancer

2.1、所需依赖

2.2、具体实现

 2.3、自定义负载均衡策略


一、LoadBalancer 负载均衡


1.1、前言

在 2020 年以前的 SpringCloud 采用 Ribbon 作为负载均衡,但是 2020 年之后,SpringCloud 吧 Ribbon 移除了,而是使用自己编写的 LoadBalancer 替代.

因此,如果在没有加入 LoadBalancer 依赖的情况下,使用 RestTemplate 或 OpenFeign 远程调用,就会报以下错误:

这就是在告诉你 LoadBalancing是未定义的(OpenFeign 中引入的依赖会使用 LoadBalancing),然后问你是不是忘记加入 spring-cloud-starter-loadbalancer 依赖.

1.2、LoadBalancer 负载均衡底层实现原理

a)在添加了 @LoadBalanced 注解之后,会启用拦截器对我们发起的服务调用请求进行拦截(注意,这里是针对我们发起的请求进行拦截),叫做 LoadBalancerInterceptor,它实现了 ClientHttpRequestInterceptor 接口:

@FunctionalInterface
public interface ClientHttpRequestInterceptor {ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException;
}

 intercept 方法如下:

public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {URI originalUri = request.getURI();String serviceName = originalUri.getHost();Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
}

主要就是这里的 intercept 方法拦截的请求.

b)这个拦截器具体做了什么事情呢,我们知道,被拦截的请求地址,并不是一个有效的主机地址,而是服务名称,因此需要通过 服务注册中心(Nacos)才能得到需要访问的主机地址.

loadBalancer.execute() 就是在获取请求对应的服务实例信息.

//从上面给进来了服务的名称和具体的请求实体
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {String hint = this.getHint(serviceId);LoadBalancerRequestAdapter<T, DefaultRequestContext> lbRequest = new LoadBalancerRequestAdapter(request, new DefaultRequestContext(request, hint));Set<LoadBalancerLifecycle> supportedLifecycleProcessors = this.getSupportedLifecycleProcessors(serviceId);supportedLifecycleProcessors.forEach((lifecycle) -> {lifecycle.onStart(lbRequest);});//可以看到在这里会调用choose方法自动获取对应的服务实例信息ServiceInstance serviceInstance = this.choose(serviceId, lbRequest);if (serviceInstance == null) {supportedLifecycleProcessors.forEach((lifecycle) -> {lifecycle.onComplete(new CompletionContext(Status.DISCARD, lbRequest, new EmptyResponse()));});//没有发现任何此服务的实例就抛异常(之前的测试中可能已经遇到了)throw new IllegalStateException("No instances available for " + serviceId);} else {//成功获取到对应服务的实例,这时就可以发起HTTP请求获取信息了return this.execute(serviceId, serviceInstance, lbRequest);}
}

 

c)因此,实际上,在进行负载均衡的时候,会向服务的注册中心(Nacos)发起一个请求,选择一个可用的服务(如果有多个),然后返回此服务的主机地址等信息.

二、整合 OpenFeign + LoadBalancer


2.1、所需依赖

在需要进行远程调用的服务中引入openfeign 和 loadbalancer 依赖

        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>

2.2、具体实现

a)启动类中添加 @EnableFeignClients 注解

@SpringBootApplication
@EnableFeignClients
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}}

b)例如,在 user 微服务中调用 article 微服务接口,那么就需要在 user 为服务中创建一个 article 的客户端.

@FeignClient("article")
public interface ArticleClient {@GetMapping("/article/start")String userStart();}

服务提供者:

@RestController
@RequestMapping("/article")
public class ArticleController {@GetMapping("/start")public String userStart() {System.out.println("article 被远程调用了!");return "article ok ~";}}

服务消费者:

@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate ArticleClient articleClient;@GetMapping("/start")public String userStart() {String result = articleClient.userStart();return "user ok ~\n" + result;}}

c)访问 user 服务接口,可以看到成功进行了远程调用

d)连续访问 10 次,可以发现,在 OpenFeign 的声明式客户端中,不用加 @LoadBalancer 注解也会实现默认的 “轮询” 负载均衡策略(RestTemplate 方式必须加).

 

在 BlockingLoadBalancerClient 中添加断点,就可以看到我们指定的策略默认是轮询(RoundRobin):

 2.3、自定义负载均衡策略

LoadBalancer默认提供了两种负载均衡策略:

  • RandomLoadBalancer - 随机分配策略
  • (默认) RoundRobinLoadBalancer - 轮询分配策略

现在希望修改默认的负载均衡策略为随机分配策略,就需要创建随机分配策略的配置类(不用加 @Configuration):

//这里不用加 @Configuration 注解
public class LoadBalancerConfig {//将官方提供的 RandomLoadBalancer 注册为Bean@Beanpublic ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory){String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}
}

通过 @LoadBalancerClient(value = "服务名", configuration = LoadBalancerConfig.class)  指定负载均衡策略为随机.

@FeignClient("article")
@LoadBalancerClient(value = "article", configuration = LoadBalancerConfig.class) //指定负载均衡策略为随机
public interface ArticleClient {//    @LoadBalanced(可以写,也可以不用写,默认所有方法都自动加 @LoadBalanced)@GetMapping("/article/start")String userStart();}

相关文章:

SpringCloud - 新版淘汰 Ribbon,在 OpenFeign 中整合 LoadBalancer 负载均衡

目录 一、LoadBalancer 负载均衡 1.1、前言 1.2、LoadBalancer 负载均衡底层实现原理 二、整合 OpenFeign LoadBalancer 2.1、所需依赖 2.2、具体实现 2.3、自定义负载均衡策略 一、LoadBalancer 负载均衡 1.1、前言 在 2020 年以前的 SpringCloud 采用 Ribbon 作为负载…...

[MySQL-基础]SQL语句

目录 hello! 这里是欧_aita的频道。 今日语录: 只有放弃才是真正的失败。 祝福语&#xff1a;愿你的代码生活充满注释&#xff0c;逻辑清晰&#xff0c;debug之路畅通无阻。 大家可以在评论区畅所欲言&#xff0c;可以指出我的错误&#xff0c;在交流中共同进步。 欢迎关注我的…...

CentOS 7实现类似于Kali Linux中的自动补全功能

在CentOS 7中&#xff0c;可以通过安装和使用Bash-completion来实现自动补全功能&#xff0c;类似于Kali Linux中的自动补全。以下是安装和使用Bash-completion的步骤&#xff1a; 首先&#xff0c;确保您的系统已更新并安装了EPEL存储库。&#xff08;非必要&#xff0c;直接…...

skywalking中gateway的拓扑图没有出现

背景&#xff1a; 刚开始的时候gateway没有出现&#xff0c;后来百度说添加插件的jar包&#xff0c; apm-spring-cloud-gateway-2.1.x-plugin-8.15.0.jar apm-spring-webflux-5.x-plugin-8.15.0.jar 然后解决了gateway节点出来了&#xff0c; 但是&#xff1a;拓扑图却是User指…...

【前端学java】java中的日期操作(12)

往期回顾&#xff1a; 【前端学java】JAVA开发的依赖安装与环境配置 &#xff08;0&#xff09;【前端学 java】java的基础语法&#xff08;1&#xff09;【前端学java】JAVA中的packge与import&#xff08;2&#xff09;【前端学java】面向对象编程基础-类的使用 &#xff08…...

用eclipse搭建简单的JavaWeb环境

在 Eclipse 中搭建 JavaWeb 项目的环境涉及到配置服务器、创建项目、添加库等步骤。以下是基于 Eclipse 的 JavaWeb 项目搭建的简要步骤&#xff1a; 步骤&#xff1a; 1. 安装 Eclipse IDE for Java EE Developers 确保你已经安装了 Eclipse IDE for Java EE Developers 版…...

【精选】改进的YOLOv5:红外遥感图像微型目标的高效识别系统

1.研究背景与意义 随着科技的不断发展&#xff0c;红外遥感技术在军事、安防、环境监测等领域中得到了广泛应用。红外遥感图像具有独特的优势&#xff0c;可以在夜间或恶劣天气条件下获取目标信息&#xff0c;因此在小目标检测方面具有重要的应用价值。然而&#xff0c;由于红…...

HarmonyOS ArkTS语言,运行Hello World(一)

一、下载与安装DevEco Studio 在HarmonyOS应用开发学习之前&#xff0c;需要进行一些准备工作&#xff0c;首先需要完成开发工具DevEco Studio的下载与安装以及环境配置。 进入DevEco Studio下载官网&#xff0c;单击“立即下载”进入下载页面。 DevEco Studio提供了Windows…...

IDEA中注释快捷键及模板

单行注释 将光标放置于要注释所在行&#xff0c;使用 Ctrl /&#xff0c; 添加行注释&#xff0c;再次使用&#xff0c;去掉行注释 若需要将多行进行单行注释&#xff0c;只需要选中要注释的多行&#xff0c;然后使用 Ctrl /&#xff0c; 添加行注释&#xff0c;再次使用&a…...

centos7系统下postgresql15离线安装,卸载

1. 创建postgres用户 #[rootVMTest postgresql16]# useradd -g postgres postgres [rootVMTest postgresql16]# useradd postgres 插曲&#xff1a;在线YUM安装 在线安装参考: PostgreSQL: Linux downloads (Red Hat family) 2. 下载并安装离线rpm包 2.1 从postgresql官网下…...

C#线程 ConcurrentQueue安全队列介绍

https://blog.csdn.net/qq_41230604/article/details/126305068 C#线程安全队列ConcurrentQueue ConcurrentQueue队列是一个高效的线程安全的队列&#xff0c;是Net Framework 4.0&#xff0c;System.Collections.Concurrent命名空间下的一个数据结构。 ConcurrentQueue内部结…...

CURL踩坑记录

因为项目使用的windows server&#xff0c;且没有安装Postman&#xff0c;所以对于在本地的Postman上执行的请求&#xff0c;要拷贝到服务器执行&#xff0c;只能先转化成为curl命令&#xff0c;操作也很简单&#xff0c;如下&#xff1a; 注意&#xff0c;Postman默认对url包围…...

Python 自动化(十八)admin后台管理

admin后台管理 什么是admin后台管理 django提供了比较完善的后台数据库的接口&#xff0c;可供开发过程中调用和测试使用 django会搜集所有已注册的模型类&#xff0c;为这些模型类提供数据管理界面&#xff0c;供开发使用 admin配置步骤 创建后台管理账号 该账号为管理后…...

Navicat 技术指引 | 适用于 GaussDB 的自动运行功能

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持对 GaussDB 主备版的管理和开发功能。它不仅具备轻松、便捷的可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结构同步、协同合作、数据迁移等&#xff09;&#xff0c;这…...

MySQL 的执行原理(四)

5.5. MySQL 的查询重写规则 对于一些执行起来十分耗费性能的语句&#xff0c;MySQL 还是依据一些规则&#xff0c;竭尽全力的把这个很糟糕的语句转换成某种可以比较高效执行的形式&#xff0c;这个过程也可以 被称作查询重写。 5.5.1. 条件化简 我们编写的查询语句的搜索条件…...

PHP 正则式 全能匹配URL(UBB)

PHP 正则式 全能匹配URL&#xff08;UBB&#xff09; 语言&#xff1a;PHP 注明&#xff1a;正则式 无语言限制&#xff08;js、PHP、JSP、ASP、VB、.net、C#...&#xff09;一切皆可。 简介&#xff1a;PHP UBB 正则式 全能匹配URL 自动加超级链接。网上找了很多都不匹配或…...

hadoop shell操作 hdfs处理文件命令 hdfs上传命令 hadoop fs -put命令hadoop fs相关命令 hadoop(十三)

hadoop fs -help rm 查看rm命令作用 hadoop fs 查看命令 1. 创建文件夹&#xff1a; # hdfs前缀也是可以的。更推荐hadoop hadoop fs -mkdir /sanguo 2.上传至hdfs命令&#xff1a; 作用&#xff1a; 从本地上传hdfs系统 &#xff08;本地文件被剪切走&#xff0c;不存在了&…...

redis-cluster集群

1.redis-cluster集群 redis3.0引入的分布式存储方案 集群由多个node节点组成&#xff0c;redis数据分布在这些节点之中。 在集群之中分为主节点和从节点 集群模式当中&#xff0c;主从一一对应&#xff0c;数据写入和读取与主从模式一样&#xff0c;主负责写&#xff0c;从…...

Hfish安全蜜罐部署

一、Hfish蜜罐介绍 HFish蜜罐官网 HFish是一款社区型免费蜜罐&#xff0c;侧重企业安全场景&#xff0c;从内网失陷检测、外网威胁感知、威胁情报生产三个场景出发&#xff0c;为用户提供可独立操作且实用的功能&#xff0c;通过安全、敏捷、可靠的中低交互蜜罐增加用户在失陷…...

Apache POI(Java)

一、Apache POI介绍 Apache POI是Apache组织提供的开源的工具包&#xff08;jar包&#xff09;。大多数中小规模的应用程序开发主要依赖于Apache POI&#xff08;HSSF XSSF&#xff09;。它支持Excel 库的所有基本功能; 文本的导入和导出是它的主要特点。 我们可以使用 POI 在…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...