SpringBoot实战(二十四)集成 LoadBalancer

目录

  • 官方文档: https://spring.io/guides/gs/spring-cloud-loadbalancer/
  • GitHub: https://github.com/spring-cloud/spring-cloud-commons/tree/main/spring-cloud-loadbalancer

一、简介

1.定义

Spring Cloud LoadBalancerSpring Cloud 框架提供的负载均衡组件,用于在微服务框架中实现服务之间的负载均衡。

2.取代 Ribbon

Spring Cloud LoadBalancer 的设计目标是简化和统一负载均衡的使用方式,并提供良好的扩展性。从 Spring Cloud 2020.0 版本、Spring Boot 2.4.x 版本开始,Spring Boot 框架官方放弃了对 Ribbon 的支持,转而使用 Spring Cloud LoadBalancer 作为默认的负载均衡器。虽然提供了与 Ribbon 类似的功能,但是与 Ribbon 相比,Spring Cloud LoadBalancer 具有更轻量级的实现,更好的性能表现,并且更适合与 Spring Cloud Gateway 等其他组件集成使用

3.主要特点与功能

Spring Cloud LoadBalancer 的主要特点和功能包括:

1)简化集成:Spring Cloud LoadBalancer 可以与 Spring Cloud 服务注册与发现组件(如 Eureka、Consul)集成,从注册中心获取服务信息,并进行负载均衡
2)内置负载均衡策略:Spring Cloud LoadBalancer 提供了一些内置的负载均衡策略,如轮询(Round Robin)随机(Random) 等,可以根据需要选择合适的负载均衡策略。
3)定制负载均衡策略:Spring Cloud LoadBalancer 还支持定制负载均衡策略,开发人员可以根据实际需求自定义负载均衡算法
4)故障转移:当某个服务节点不可用时,Spring Cloud LoadBalancer 可以自动将请求发送到其他可用的节点,提高系统的可靠性和容错性。
5)可扩展性:Spring Cloud LoadBalancer 提供了扩展点,开发人员可以根据需要进行扩展和定制,以满足特定的负载均衡需求。

在使用 Spring Cloud LoadBalancer 时,可以通过相关的依赖和配置来进行集成和使用。它可以与其他 Spring Cloud 组件(如 Spring Cloud Gateway、Spring Cloud OpenFeign 等)一起使用,为应用程序提供完整的微服务环境。

4.LoadBalancer 和 OpenFeign 的关系

很多人一直认为 OpenFeign 和 LoadBalancer 的关系就是简单的包含,其实这种看法是错误的。我们可以看看 Spring Cloud 里产品 Map 图里的关系,就一目了然了。

在这里插入图片描述

OpenFeign 的定位是 annotation 化的 RESTFUL Client。需要认识到 OpenFeign 的本质其实是 Spring Cloud 里面比 RestTemplate 更高阶的一个升级组件,实现的是 RESTFUL Client,只是通过 Open Feign 的一些 annotaion 可以实现的比较简单而已。

在这里插入图片描述

LoadBalancer 是 Spring Cloud 里的一个 Common 组件,是可以给其他组件提供服务的基础组件。使用 LoadBalancer 无需 Open Feign 的集成打开 LoadBalancer 的支持功能,有关 RestTemplate 的地方就可以实现客户端的负载均衡了,OpenFeign 是 RestTemplate 的扩展,当然也就同样可以支持到负载均衡。

细心的朋友可以发现,咱们下面介绍的有关 Loadbalance 的使用,基本上都是和 OpenFeign 没有任何联系的; OpenFeign 只是我们后来进行验证效果的方式。


二、使用场景一:Eureka + LoadBalancer

服务架构图如下:

在这里插入图片描述

服务列表如下:

在这里插入图片描述

服务A:loadbalancer-consumer 消费者

1.Maven依赖

注意:这里的 LoadBalancer 依赖必须引入,否则即使编译不报错,负载均衡也是失效的。

<!-- Web -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency><!-- Eureka -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency><!-- LoadBalancer -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

2.application.yml配置

server:port: 8081spring:application:name: loadbalancer-consumer#eureka client
eureka:client:service-url:defaultZone: http://demo:Demo2023@localhost:1001/eureka/instance:hostname: localhostprefer-ip-address: true # 是否使用 ip 地址注册instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:portlease-renewal-interval-in-seconds: 5 # 实例续期心跳间隔(默认30s),设置之后启动服务不需要等很久就可以访问到服务的内容lease-expiration-duration-in-seconds: 15 # 实例续期持续多久后失效(默认90s)

3.RestTemplateConfig.java

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;/*** <p> @Title RestTemplateConfig* <p> @Description RestTemplate配置类** @author zhj* @date 2023/9/17 20:58*/
@Configuration
public class RestTemplateConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}

4.DemoController.java

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;/*** <p> @Title DemoController* <p> @Description 测试Controller** @author ACGkaka* @date 2023/4/24 18:02*/
@Slf4j
@RestController
@RequestMapping("/demo")
public class DemoController {@Autowiredprivate RestTemplate restTemplate;@RequestMapping("/consumeTest")public Object test() {log.info(">>>>>>>>>>【INFO】DemoController.consumeTest()...");String url = "http://loadbalancer-producer/demo/produceTest";return restTemplate.getForObject(url, Object.class);}
}

服务B:loadbalancer-producer 生产者

1.Maven依赖

<!-- Web -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency><!-- Eureka -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2.application.yml配置

server:port: 8082spring:application:name: loadbalancer-producer#eureka client
eureka:client:service-url:defaultZone: http://demo:Demo2023@localhost:1001/eureka/instance:hostname: localhostprefer-ip-address: true # 是否使用 ip 地址注册instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:portlease-renewal-interval-in-seconds: 5 # 实例续期心跳间隔(默认30s),设置之后启动服务不需要等很久就可以访问到服务的内容lease-expiration-duration-in-seconds: 15 # 实例续期持续多久后失效(默认90s)

3.DemoController.java

import com.demo.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** <p> @Title DemoController* <p> @Description 测试Controller** @author ACGkaka* @date 2023/4/24 18:02*/
@Slf4j
@RestController
@RequestMapping("/demo")
public class DemoController {@Value("${server.port}")private String port;@RequestMapping("/produceTest")public Result<Object> produceTest() {Result<Object> result = Result.succeed();log.info(">>>>>>>>>>【INFO】DemoController.produceTest()...");return result.setData("Hello, I'm from port: " + port);}
}

调用测试

请求地址:http://localhost:8081/demo/consumeTest

可以发现分别打印了不同的服务端口,说明负载生效:

在这里插入图片描述

在这里插入图片描述


三、使用场景二:Eureka + LoadBalancer + OpenFeign

服务架构图如下:

在这里插入图片描述

服务列表如下:

在这里插入图片描述

服务A:loadbalancer-feign-a

1.Maven依赖

<!-- Web -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency><!-- Eureka -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency><!-- OpenFeign -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.application.yml配置

server:port: 8081spring:application:name: loadbalancer-feign-a#eureka client
eureka:client:service-url:defaultZone: http://demo:Demo2023@localhost:1001/eureka/instance:hostname: localhostprefer-ip-address: true # 是否使用 ip 地址注册instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:portlease-renewal-interval-in-seconds: 5 # 实例续期心跳间隔(默认30s),设置之后启动服务不需要等很久就可以访问到服务的内容lease-expiration-duration-in-seconds: 15 # 实例续期持续多久后失效(默认90s)##feign参数优化
feign:client:config:# 这里用 default 就是全局配置,如果是写服务名称,则是针对某个服务的配置。default:# 日志级别(忽略大小写),包括:NONE(默认)、BASIC、HEADERS、FULLloggerLevel: FULL

3.DemoController.java

import com.demo.common.Result;
import com.demo.feign.DemoFeignClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RestController
@RequestMapping("/demo")
public class DemoController {@Value("${server.port:}")private String port;@Autowiredprivate DemoFeignClient demoFeignClient;@GetMapping("/feignTest")public Result<Object> feignTest() {return demoFeignClient.test();}
}

4.DemoFeignClient.java

import com.demo.common.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;@FeignClient(value = "loadbalancer-feign-b")
public interface DemoFeignClient {@GetMapping("/demo/test")Result<Object> test();
}

服务B:loadbalancer-feign-b

1.Maven依赖

<!-- Web -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency><!-- Eureka -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2.application.yml配置

server:port: 8082spring:application:name: loadbalancer-feign-b#eureka client
eureka:client:service-url:defaultZone: http://demo:Demo2023@localhost:1001/eureka/instance:hostname: localhostprefer-ip-address: true # 是否使用 ip 地址注册instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:portlease-renewal-interval-in-seconds: 5 # 实例续期心跳间隔(默认30s),设置之后启动服务不需要等很久就可以访问到服务的内容lease-expiration-duration-in-seconds: 15 # 实例续期持续多久后失效(默认90s)

3.DemoController.java

import com.demo.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RestController
@RequestMapping("/demo")
public class DemoController {@Value("${server.port:}")private String port;@GetMapping("/test")public Result<Object> test() {String data = "This is a test! port:" + port;log.info(">>>>>>>>>> 【INFO】data:{}", data);return Result.succeed().setData(data);}
}

调用测试

请求地址:http://localhost:8081/demo/feignTest

可以发现分别打印了不同的服务端口,说明负载生效:

在这里插入图片描述

在这里插入图片描述

整理完毕,完结撒花~ 🌻





参考地址:

1.SpringCloud集成LoadBalance,负载均衡,https://blog.csdn.net/inthirties/article/details/126821335

2.SpringBoot 2 使用 SpringCloud LoadBalancer 实现客户端负载均衡,https://blog.csdn.net/stevenchen1989/article/details/105009292

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

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

相关文章

笔记01:第一行Python

NameError 名字不含特殊符号&#xff08;只能是英文、数字、下划线、中文等&#xff09;名字区分大小写名字先定义后使用 SyntaxError 不符合Python语法书写规范除了语法成分中的保留拼写错误输出中文符号if、for、def等语句末尾忘记冒号 IdentationError 缩进错误&#x…

C# Onnx Yolov8 Detect 物体检测

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System…

开源即时通讯(IM)项目OpenIM源码部署流程

由于OpenIM依赖的组件较多&#xff0c;开发者需求不一&#xff0c;导致OpenIM部署一直被人诟病&#xff0c;经过几次迭代优化&#xff0c;包括依赖的组件compose的一键部署&#xff0c;环境变量设置一次&#xff0c;全局生效&#xff0c;以及脚本重构&#xff0c;目前OpenIM部署…

2023CSP游寄

初赛 DAY -2 才刚考开学测就来初赛。 复赛之后就是月测&#xff0c;这就是初三吗。 初中最后一次 CSP&#xff0c;如果 S 没一等就得摆烂了。希望别因为各种原因爆炸。 中午下午借着刷初赛题的名义摆烂&#xff0c;半道题都没写。 CSP2023RP 初赛 DAY -1 看我发现了什么。…

SpringBoot 集成 SpringSecurity 从入门到深入理解

完整的目录 介绍 SpringSecurity简述 SpringSecuritySpringSecurity 的主要功能说明 项目源码入门案例项目工程路径第一步&#xff1a;加载依赖第二步&#xff1a;创建核心的配置类第三步&#xff1a;增加controller第三步&#xff1a;启动程序小结界面跳转说明密码生成说明 重…

使用Python来写模拟Xshell实现远程命令执行与交互

一、模块 这里使用的是 paramiko带三方库 pip install paramiko二、效果图 三、代码实现&#xff08;这里的IP&#xff0c;用户名&#xff0c;密码修改为自己对应服务器的&#xff09; import paramiko import timeclass Linux(object):# 参数初始化def __init__(self, ip, us…

python 使用requests爬取百度图片并显示

爬取百度图片并显示 引言一、图片显示二、代码详解2.1 得到网页内容2.2 提取图片url2.3 图片显示 三、完整代码 引言 爬虫&#xff08;Spider&#xff09;&#xff0c;又称网络爬虫&#xff08;Web Crawler&#xff09;&#xff0c;是一种自动化程序&#xff0c;可以自动地浏览…

【前端知识】Three 学习日志(四)—— 相机控件

Three 学习日志&#xff08;四&#xff09;—— 相机控件 一、引入相机控件 <!-- 引入相机控件 --> <script type"importmap">{"imports": {"three": "../build/three.module.js","three/addons/": "../…

C#,数值计算——Hashtable的计算方法与源程序

1 文本格式 using System; using System.Collections; using System.Collections.Generic; namespace Legalsoft.Truffer { public abstract class Hashtable<K> { private int nhash { get; set; } private int nmax { get; set; } pr…

Vue3记录

Vue3快速上手 1.Vue3简介 2020年9月18日&#xff0c;Vue.js发布3.0版本&#xff0c;代号&#xff1a;One Piece&#xff08;海贼王&#xff09;耗时2年多、2600次提交、30个RFC、600次PR、99位贡献者github上的tags地址&#xff1a;https://github.com/vuejs/vue-next/releas…

Vue3搭配Element Plus 实现候选搜索框效果

直接上代码 <el-col :span"14" class"ipt-col"><el-input v-model"projectName" class"w-50 m-2" input"inputChange" focus"inputFocusFn" blur"inputBlurFn" placeholder"请输入项目名…

同样的UWB,为什么定位精度差很多?

纵观以UWB技术为核心的应用与电厂、化工厂等工业企业人员定位系统&#xff0c;在定位精度上都声称能够达到厘米级精准&#xff0c;然而实际应用上却总是差了些许意思。任何产品都有理论值与实际值&#xff0c;例如某些新能源汽车号称标准续航300公里&#xff0c;但实际上可能连…

【面试题】智力题

文章目录 腾讯1000瓶毒药里面只有1瓶是有毒的&#xff0c;问需要多少只老鼠才能在24小时后试出那瓶有毒。有两根不规则的绳子&#xff0c;两根绳子从头烧到尾均需要一个小时&#xff0c;现在有一个45分钟的比赛&#xff0c;裁判员忘记带计时器&#xff0c;你能否通过烧绳子的方…

C++---异常处理

异常处理 异常处理try语句块和throw表达式异常的抛出和捕获异常的抛出和匹配原则 异常安全异常规范标准异常 异常处理 异常是指存在于运行时的反常行为&#xff0c;这些行为超出了函数正常功能的范围。当程序的某部分检测到一个他无法处理的问题时&#xff0c;需要用到异常处理…

transforms数据预处理【图像增强】 ->(个人学习记录笔记)

文章目录 1. 安装2. transforms——Crop 裁剪2.1 transforms.CenterCrop2.2 transforms.RandomCrop2.3 transforms.RandomResizedCrop2.4 transforms.FiveCrop2.5 transforms.TenCrop 3. transforms——Flip 翻转3.1 transforms.RandomHorizontalFlip3.2 transforms.RandomVert…

leetcode 817. 链表组件(java)

链表组件 题目描述HashSet 模拟 题目描述 给定链表头结点 head&#xff0c;该链表上的每个结点都有一个 唯一的整型值 。同时给定列表 nums&#xff0c;该列表是上述链表中整型值的一个子集。 返回列表 nums 中组件的个数&#xff0c;这里对组件的定义为&#xff1a;链表中一段…

zabbix学习1--zabbix6.x单机

文章目录 1. 环境2. MYSQL8.02.1 单节点2.2 配置主从 3. 依赖组件4. zabbix-server5. agent5.1 yum5.2 编译 附录my.cnfJDK默认端口号 1. 环境 进入官网查看所需部署环境配置以及应用版本要求https://www.zabbix.com/documentation/current/zh/manual/installation/requiremen…

MySQL 解决数据重复添加

1. sql语句: insert ignore into insert ignore into 表名 (xx1,xx2,xx3) VALUES (#{xx1},#{xx2},#{xx3}) 2. 复合索引

7-38 掉入陷阱的数字

输入样例: 5 输出样例: 1:16 2:22 3:13 4:13 ACcode: #include <bits/stdc.h>using namespace std;int main(){int n;cin >> n;vector<int> ans;int limit 1;ans.push_back(n);for(int i0; i<limit; i){//各位数字的和int sum 0;int num ans[i];w…

echarts的折线图,在点击图例后,提示出现变化,不报错。tooltip的formatter怎么写

在点击图例的年后&#xff0c;提示框会相应的变化&#xff0c;多选和单选都会响应变化。tooptip的重度在formatter tooltip:{show:true,trigger:"axis",alwaysShowContent:true,triggerOn:"mousemove",textStyle:{color:"#fff"},backgroundColor…