SpringBoot实战(二十四)集成 LoadBalancer

news2024/12/26 22:20:22

目录

  • 官方文档: 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: 8081

spring:
  application:
    name: loadbalancer-consumer

#eureka client
eureka:
  client:
    service-url:
      defaultZone: http://demo:Demo2023@localhost:1001/eureka/
  instance:
    hostname: localhost
    prefer-ip-address: true # 是否使用 ip 地址注册
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
    lease-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
    @LoadBalanced
    public 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 {

    @Autowired
    private 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: 8082

spring:
  application:
    name: loadbalancer-producer

#eureka client
eureka:
  client:
    service-url:
      defaultZone: http://demo:Demo2023@localhost:1001/eureka/
  instance:
    hostname: localhost
    prefer-ip-address: true # 是否使用 ip 地址注册
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
    lease-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: 8081

spring:
  application:
    name: loadbalancer-feign-a

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

##feign参数优化
feign:
  client:
    config:
      # 这里用 default 就是全局配置,如果是写服务名称,则是针对某个服务的配置。
      default:
        # 日志级别(忽略大小写),包括:NONE(默认)、BASIC、HEADERS、FULL
        loggerLevel: 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;

    @Autowired
    private 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: 8082

spring:
  application:
    name: loadbalancer-feign-b

#eureka client
eureka:
  client:
    service-url:
      defaultZone: http://demo:Demo2023@localhost:1001/eureka/
  instance:
    hostname: localhost
    prefer-ip-address: true # 是否使用 ip 地址注册
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
    lease-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.coloradmin.cn/o/1019236.html

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

相关文章

浏览器事件机制详解

目录 前言 事件类型 鼠标事件 表单事件 窗口事件 DOM事件 多媒体事件 拖拽与放置事件 移动设备事件 剪切板事件 错误事件 过渡、动画事件 事件监听 onevent addEventListener(event) 事件触发 事件流程 捕获阶段 目标阶段 冒泡阶段 事件对象 总结 相关代…

记一次 .NET 某电力系统 内存暴涨分析

一&#xff1a;背景 1. 讲故事 前些天有位朋友找到我&#xff0c;说他生产上的程序有内存暴涨情况&#xff0c;让我帮忙看下怎么回事&#xff0c;最简单粗暴的方法就是让朋友在内存暴涨的时候抓一个dump下来&#xff0c;看一看大概就知道咋回事了。 二&#xff1a;Windbg 分…

Stream之实现原理分析

文章目录 1 Stream原理1.1 引言1.2 操作分类1.3 操作分类例子分析1.4 一种直白的实现方式1.5 Stream流水线解决方案1.5.1 操作如何记录1.5.2 操作如何叠加1.5.3 叠加之后的操作如何执行1.5.4 执行后的结果在哪里 1 Stream原理 1.1 引言 我们已经学会如何使用 Stream API&…

(vue的入门

vue的入门 一. Vue是什么二. Vue的特点及优势三. 使用Vue的详细步骤四. Vue的基本语法五. Vue的生命周期 一. Vue是什么 Vue&#xff08;发音为/“vjuː”/&#xff0c;类似于"view"&#xff09;是一套用于构建用户界面的渐进式JavaScript框架。它是一个开源的、轻量…

[字符串和内存函数]strcmp字符串函数的详解和模拟

strcmp函数 strcmp函数是一个用于比较两个字符串的C标准库函数。它的原型为&#xff1a; int strcmp(const char* str1, const char* str2);strcmp函数会比较str1和str2两个字符串的字符序列&#xff0c;并返回一个整数值来表示它们之间的大小关系。返回值的含义如下&#xff…

2023-简单点-IOU计算

机器视觉中的坐标体系 注意区分x,y坐标系和row,col排布 IOU交集 代码 def IOU(RecA, RecB):recA是坐标形式是[X[左上点],y[左上点],x[右下点],y[右下点]]#找到交集框的左上和右下点&#xff0c;可以计算交集面积xA max(RecA[0], RecB[0])yA max(RecA[1], RecB[1])xB min(R…

R reason ‘拒绝访问‘的解决方案

Win11系统 安装rms的时候报错&#xff1a; Error in loadNamespace(j <- i[[1L]], c(lib.loc, .libPaths()), versionCheck vI[[j]]) : namespace Matrix 1.5-4.1 is already loaded, but > 1.6.0 is required## 安装rms的时候报错&#xff0c;显示Matrix的版本太低…

SmFeN钐铁氮稀土永磁材料

钕铁硼作为第三代稀土永磁材料&#xff0c;因其优异的磁性能而获得了广泛应用。但钕铁硼磁体也存在居里温度低&#xff0c;矫顽力温度系数大以及化学稳定性差等缺点&#xff0c;并且镨、钕、镝、铽稀土资源的巨量消耗引发了人们对环境破坏和稀土资源保障可持续性的担忧。因此磁…

小红书产品文案怎么创作,达人投放技巧总结

每一个文案都有一个10万的梦。该如何快速写出爆款产品文案&#xff0c;让消费者在读到文案的第一分钟&#xff0c;就被产品深深吸引呢&#xff0c;今天来给大家分享下小红书产品文案怎么创作&#xff0c;达人投放技巧总结&#xff01; 一、文案的三大关键 影响一篇文案阅读量的…

天翎知识管理系统:强大的权限管理功能,保障知识安全

编者按&#xff1a; 知识管理系统的权限管理功能&#xff0c;可以帮助企业实现对知识库的精细化管理&#xff0c;保证知识库的安全性和稳定性。本文将介绍天翎知识管理系统的权限管理体系&#xff0c;通过权限管理&#xff0c;控制用户的编辑和审核权限&#xff0c;从而保证知识…

05. OpenFeign 服务调用

Spring Cloud 微服务系列文章&#xff0c;点击上方合集↑ 1. 简介 微服务架构中使用OpenFeign进行服务调用&#xff0c;OpenFeign提供了一种简洁的方式来定义和处理服务间的调用。 OpenFeign作为一个声明式的、模块化的HTTP客户端&#xff0c;通过接口的定义和注解的使用&…

docker安装es docker安装Elasticsearch windows linux

下载Elasticsearch和Kibana镜像docker pull elastic/elasticsearch:8.8.2 docker pull elastic/kibana:8.8.2 2. 设置max_map_countwindows&#xff1a; wsl -d docker-desktop sysctl -w vm.max_map_count262144 exit linux&#xff1a;cat /proc/sys/vm/max_map_count sys…

32:TX Text Control ActiveX/ASP.NET/WinForms/WPF Crack

TX Text Control ActiveX 32.0 添加操作“普通”样式表的能力。 2023 年 9 月 14 日 - 15:38新版本 特征 脚注- 在文档中插入与 Microsoft Word 兼容的脚注。脚注是一种文字处理功能&#xff0c;允许用户在页面底部插入附加信息。 可编辑的[普通]样式表- 添加了操作[普通]样式的…

虚拟人运营 | 金融品牌如何借助数字人IP撬动年轻圈层?

近年来&#xff0c;金融行业在不断尝试寻找一种新方式&#xff0c;去探索触及Z世代年轻圈层&#xff0c;数字人作为数字化时代的新介质&#xff0c;成为了金融业链接年轻人的新载体。 在银行的应用场景里&#xff0c;主要打造智能客服、数字员工、虚拟主播等。如浦发银行数字员…

李宏毅hw-6利用GAN生成动漫图像

一、查漏补缺、熟能生巧&#xff1a; 1.什么是转置卷积convTranspose、以及这种转置卷积怎么使用&#xff1a; &#xff08;1&#xff09;具体的原理直接看李沐老师的那个演示&#xff0c;非常清晰&#xff1a; 47 转置卷积【动手学深度学习v2】_哔哩哔哩_bilibili &#x…

无涯教程-JavaScript - INT函数

描述 INT函数将数字四舍五入到最接近的整数。 语法 INT (number)争论 Argument描述Required/OptionalNumberThe real number you want to round down to an integer.Required 适用性 Excel 2007,Excel 2010,Excel 2013,Excel 2016 Example JavaScript 中的 INT函数 - 无…

2023Web前端逻辑面试题

1、现有9个小球&#xff0c;已知其中一个球比其它的重&#xff0c;如何只用天平称2次就找出该球&#xff1f; ①把9个球分成三份&#xff0c;三个一份&#xff1b; ②拿出其中两份进行称量&#xff1b;会分为两种情况 若拿出的两份小球称量结果&#xff0c;重量相等&#xff1b…

idea 启动命令过长

报错: 运行 MyBatisPlusGenerator35Template 时出错。命令行过长。 缩短命令行并重新运行。 解决:

【JVM】Java类的加载机制!

一、类的生命周期 类加载过程包含&#xff1a;加载、验证、准备、解析和初始化 &#xff0c;一共包括5 个阶段。 &#xff08;1&#xff09;加载&#xff1a; 简单来说就是将java类的字节码文件加载到机器内存中。在加载类时&#xff0c;Java虚拟机必须完成以下3件事情&…

Matlab图像处理-HSI模型

HSI模型 HSI模型是从人的视觉系统出发&#xff0c;直接使用颜色三要素色调(Hue)、饱和度(Saturation)和亮度&#xff08;Intensity&#xff09;来描述颜色。 亮度是指人眼感知光线的明暗程度。光的能量越大&#xff0c;亮度就越大。 色调是颜色最重要的属性。 它决定了颜色的…