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();}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Flask使用】全知识md文档,4大部分60页第3篇:Flask模板使用和案例

本文的主要内容&#xff1a;flask视图&路由、虚拟环境安装、路由各种定义、状态保持、cookie、session、模板基本使用、过滤器&自定义过滤器、模板代码复用&#xff1a;宏、继承/包含、模板中特有变量和函数、Flask-WTF 表单、CSRF、数据库操作、ORM、Flask-SQLAlchemy…

Visual NLP:图像信息自动提取的未来

本文旨在以简单的方式解释 Visual NLP 的关键概念&#xff0c;让你了解 Visual NLP 的含义、它的用例是什么、如何使用它以及为什么它是构建自动提取管道的未来 。 NSDT在线工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在…

在线工具收集

在线工具收集 1、在线P图 https://www.photopea.com/ 一款类似于PS的在线抠图软件 ①去除图片中的文字&#xff0c;并填充背景色 第一步&#xff1a;使用矩形选中要清除的文字 第二步&#xff1a;点击编辑选择填充 第三步&#xff1a;选择内容识别&#xff0c;保留透明区域…

趋势解读:TikTok独创的社交语言是如何演变的

在数字时代的浪潮中&#xff0c;社交媒体平台成为人们传递信息、表达创意和建立社交联系的重要场所。而在这众多社交平台中&#xff0c;TikTok以其独特的社交语言和创新的内容形式&#xff0c;迅速吸引了全球数以亿计的用户。本文将深入探讨TikTok的社交语言是如何独创并演变的…

使用Python画一棵树

&#x1f38a;专栏【不单调的代码】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 &#x1f970;欢迎并且感谢大家指出我的问题 文章目录 &#x1f339;Turtle模块&#x1f384;效果&#x1f33a;代码&#x1f6f8;代码…

IvorySQL3.0:基于PG16.0最新内核,实现兼容Oracle数据库再升级

Oracle作为全球最大的数据库厂商之一&#xff0c;具有较高的市场知名度和份额。但随着数据处理需求日益增长&#xff0c;使用Oracle的企业可能面临一些挑战&#xff0c;如数据库复杂性、高昂维护成本、数据迁移和集成问题等&#xff0c;难以满足企业实时数据处理需求&#xff0…

练习八-利用有限状态机进行时序逻辑的设计

利用有限状态机进行时序逻辑的设计 1&#xff0c;任务目的&#xff1a;2&#xff0c;RTL代码&#xff0c;及原理框图3&#xff0c;测试代码&#xff0c;输出波形 1&#xff0c;任务目的&#xff1a; &#xff08;1&#xff09;掌握利用有限状态机实现一般时序逻辑分析的方法&am…

第二十章 多线程

20.2创建线程 20.2.1继承Thread类 Thread类是Java.lang包中的一个类&#xff0c;从这个类中实例化的对象代表线程&#xff0c;程序员启动一个新线程需要建议Thread实例。 public class ThreadTest extedns Thread{} run方法格式&#xff1a; public void run(){} 20.1让线…

matplotlib

设置中文字体&#xff0c;图片大小&#xff0c;分辨率&#xff0c;中文负号 符号 x轴和y轴 设置x轴和y轴的刻度 字体大小 线条样式 绘制多个线条 图例 显示每个坐标值 gca 分辨率 画布尺寸 创建图形对象 不能直接使用区域对象作画 绘制多子图 均等的划分画布 柱状图 同一位置多…

Ocam——自由录屏工具~

当我们想要做一些混剪、恶搞类型的视频时&#xff0c;往往需要源影视作品中的诸多素材&#xff0c;虽然可以通过裁减mp4文件的方式来获取片段&#xff0c;但在高画质的条件下&#xff0c;mp4文件本身通常会非常大&#xff0c;长此以往&#xff0c;会给剪辑工作带来诸多不便&…

GDB Debugging Notes

1 Debugging programs using gdb 1.1 gdb简介 gdb是一个功能强大的调试工具&#xff0c;可以用来调试C程序或C程序。在使用这个工具进行程序调试时&#xff0c;主要涉及下面几个方面的操作&#xff1a; 启动程序:在启动程序时&#xff0c;可以设置程序运行环境。设置断点:程序…

使用kafka_exporter监控Kafka

prometheus 监控 kafka 常见的有两种开源方案,一种是传统的部署 exporter 的方式,一种是通过 jmx 配置监控, 项目地址: kafka_exporter:https://github.com/danielqsj/kafka_exporterjmx_exporter:https://github.com/prometheus/jmx_exporter本文将采用kafka_exporter方…

matlab使用scatter函数画图时报错“数组索引必须为正整数或逻辑值”解决办法

一、背景 在使用matlab的scatter函数画图时报错“数组索引必须为正整数或逻辑值”。 scatter函数说明&#xff1a;scatter(x,y) 在向量 x 和 y 指定的位置创建一个包含圆形标记的散点图。 二、解决办法 如果使用scatter函数时报上述错误&#xff0c;尝试将连续函数先转换为函…

ubuntu编译sqlite3并使用

SQLite3是一种轻量级的关系型数据库管理系统&#xff0c;它是在C语言基础上实现的。SQLite3具有许多优点&#xff0c;例如&#xff1a; 1.灵活&#xff1a;它可以在多种操作系统上运行&#xff0c;并且可以将多个数据库文件合并成一个文件。 2.易于使用&#xff1a;SQLite3使用…

Centos上安装Docker和DockerCompose

安装Docker Docker可以运行在MAC&#xff0c;Windows&#xff0c;CtenOS,UBUNTU等操作系统上。目前主流的版本有Docker CE和Docker EE&#xff0c;CE是免费的开源Docker版本&#xff0c;适用于开发人员和小型团队&#xff0c;EE是适用于企业的容器化解决方案。它基于Docker CE…

如何判断交流回馈老化测试负载是否合格?

交流回馈老化测试负载是用于模拟实际工作环境中设备运行状态的测试工具&#xff0c;主要用于检测设备的耐久性和稳定性。 负载性能&#xff1a;需要检查负载的性能是否符合设计要求&#xff0c;这包括负载的功率、电流、电压等参数是否在规定的范围内&#xff0c;以及负载的工作…

可编程交流回馈式负载箱在电源设备中的应用

可编程交流回馈式负载箱可以用于测试电源设备的输出能力&#xff0c;通过在负载箱中设置不同的负载条件&#xff0c;可以模拟不同的工作负载情况&#xff0c;从而测试电源设备在不同负载下的输出能力和稳定性。这对于电源设备的设计和生产非常重要&#xff0c;可以帮助制造商评…

打造高效医患沟通:陪诊小程序开发技术指南

随着科技的不断发展&#xff0c;陪诊小程序作为医患沟通的新工具逐渐成为关注焦点。本文将带领你通过使用React和Node.js技术栈&#xff0c;构建一个功能强大且用户友好的陪诊小程序&#xff0c;实现医患互动的便捷和高效。 1. 准备工作 确保你的开发环境中已安装了Node.js和…

037、目标检测-算法速览

之——常用算法速览 目录 之——常用算法速览 杂谈 正文 1.区域卷积神经网络 - R-CNN 2.单发多框检测SSD&#xff0c;single shot detection 3.yolo 杂谈 快速过一下目标检测的各类算法。 正文 1.区域卷积神经网络 - R-CNN region_based CNN&#xff0c;奠基性的工作。…

原来 TinyVue 组件库跨框架(Vue2、Vue3、React、Solid)是这样实现的?

本文由 TinyVue 组件库核心成员郑志超分享&#xff0c;首先分享了实现跨框架组件库的必要性&#xff0c;同时通过演示Demo和实际操作向我们介绍了如何实现一个跨框架的组件库。 前言 前端组件库跨框架是什么&#xff1f; 前端组件库跨框架是指在不同的前端框架&#xff08;如…