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

Spring Boot 邂逅Netty:构建高性能网络应用的奇妙之旅

一、引言

在当今数字化时代,构建高效、可靠的网络应用是开发者面临的重要挑战。Spring Boot 作为一款强大的 Java 开发框架,以其快速开发、简洁配置和丰富的生态支持,深受广大开发者喜爱。而 Netty 作为高性能、异步的网络通信框架,在处理高并发、低延迟的网络通信场景中表现卓越。当 Spring Boot 与 Netty 强强联手,将为我们带来前所未有的开发体验,开启构建高性能网络应用的新篇章。本文将深入探讨 Spring Boot 与 Netty 的结合,不仅介绍它们各自的特点和优势,还会通过实际案例详细阐述如何在 Spring Boot 项目中集成 Netty,让你轻松掌握这一强大的技术组合,为开发出更加出色的网络应用奠定坚实基础。

二、Spring Boot 与 Netty 简介

2.1 Netty:组件

Bootstrap

Netty Bootstrap 是 Netty 框架中用于配置和启动客户端或服务器端网络应用程序的重要组件

主要功能
  • 配置网络参数:Bootstrap 可用于配置网络应用程序的各种参数,如端口号、地址、线程模型、传输协议等。
  • 创建 Channel:负责创建并初始化 Channel,这是网络通信的基础,通过它可以进行数据的传输和接收。
  • 添加处理器:可以添加多个处理器(ChannelHandler)到 ChannelPipeline 中,以处理不同的业务逻辑,如编解码、业务逻辑处理等。
EventLoopGroup

EventLoopGroup扩展了Reactor线程的功能,用一个线程池实现了多个Reactor线程负责的工作,充分利用了CPU的并发处理能力。

  1. Boss EventLoopGroup负责监听客户端的连接,
  2. Work EventLoopGroup是处理IO及数据传输。

Boss EventLoopGroup监听客户端的连接,接受客户端的连接后将之后的IO处理及数据传输都交给Work EventLoopGroup。

主要功能
  • 管理 EventLoop:EventLoopGroup 是一组 EventLoop 的容器,它负责管理和分配这些 EventLoop 到不同的 Channel。在 Netty 中,EventLoop 是一个可以处理 I/O 操作和事件的执行单元。
  • 任务调度:EventLoopGroup 可以为其管理的 EventLoop 分配任务,这些任务可以是 I/O 操作、用户自定义的任务或者是定时任务等。例如,当一个 Channel 被注册到 EventLoop 时,它的 I/O 操作(如读、写、连接等)会由该 EventLoop 负责处理。
  • 线程管理:EventLoopGroup 通常会使用多线程来提高并发处理能力。不同的 EventLoop 会在不同的线程中运行,从而可以同时处理多个 Channel 的 I/O 操作和事件。
Channel

netty中的channel提供的功能类似NIO中的SocketChannel,是数据传输的通道。

主要功能
  • 数据传输:Channel 是 Netty 中进行数据传输的核心组件,它提供了基本的 I/O 操作接口,包括读(read)、写(write)和连接(connect)等操作。通过 Channel,可以在客户端和服务器之间发送和接收数据。
  • 事件处理:Channel 可以触发各种事件,例如通道连接、通道可读写、通道关闭等,这些事件可以被注册在 ChannelPipeline 中的 ChannelHandler 所处理。
  • 资源管理:Channel 负责管理与之相关的资源,如网络连接、缓冲区等。
ByteBuf

ByteBuf 是 Netty 中用于处理字节缓冲区的重要组件,它提供了比 Java 原生 ByteBuffer 更强大、更灵活的功能

主要方法
  • 读写操作方法
    • writeByte(int value):将一个字节写入到 ByteBuf 中,写入后写指针会自动后移一位。
    • writeInt(int value):将一个 32 位整数写入到 ByteBuf 中,写指针后移 4 位。
    • readByte():从 ByteBuf 中读取一个字节,读取后读指针后移一位。
    • readInt():从 ByteBuf 中读取一个 32 位整数,读指针后移 4 位。
  • 容量操作方法
    • capacity():返回 ByteBuf 的当前容量。
    • ensureWritable(int minWritableBytes):确保 ByteBuf 有足够的可写空间,如果当前可写空间不足,会自动扩展缓冲区的容量。
    • maxCapacity():返回 ByteBuf 的最大容量。
  • 索引操作方法
    • readerIndex():返回当前的读指针索引。
    • writerIndex():返回当前的写指针索引。
    • setReaderIndex(int index):设置读指针的索引位置。
    • setWriterIndex(int index):设置写指针的索引位置。
内存分配方式
  • 堆内存(Heap ByteBuf):数据存储在 JVM 的堆内存中,优点是分配和释放速度快,可通过 Java 的垃圾回收机制自动管理内存,缺点是在进行网络传输或与其他系统交互时,可能需要额外的拷贝操作。
  • 直接内存(Direct ByteBuf):数据存储在 JVM 堆外的直接内存中,能减少数据在堆内存和物理内存之间的拷贝,提高 I/O 操作性能,常用于高性能、低延迟的网络应用,但分配和释放内存的开销相对较大,且需要手动管理内存,防止内存泄漏。
ChannelFuture

ChannelFuture 是 Netty 框架中用于处理异步 I/O 操作结果的接口

常用方法
  • isSuccess():检查操作是否成功完成,操作成功返回true,否则返回false
  • cause():获取导致操作失败的异常,操作成功完成则返回null
  • isDone():检查操作是否已经完成,无论成功还是失败,完成则返回true,否则返回false
  • sync():阻塞当前线程直到操作完成,如果操作失败,则抛出异常。
  • await():等待操作完成,但不会抛出异常,可以选择等待的时间。
  • addListener(ChannelFutureListener listener):向ChannelFuture添加一个监听器,当操作完成时触发该监听器。

 

2.2 Spring Boot:Java 开发的便捷之选

Spring Boot 是由 Pivotal 团队开发的开源框架,它致力于简化 Spring 应用的初始搭建及开发过程。其核心特性之一是自动配置,通过扫描项目的类路径和已添加的依赖,Spring Boot 能够自动配置应用程序的各种组件和功能。比如,当项目中引入了spring-boot-starter-web依赖时,Spring Boot 会自动配置 Tomcat 服务器和 Spring MVC 框架,让开发者无需手动进行繁琐的配置,就能快速搭建起一个 Web 应用的基础架构,大大减少了手动配置的工作量,降低了配置出错的风险。

Spring Boot 还提供了内嵌服务器,如 Tomcat、Jetty 和 Undertow。这意味着开发者可以直接通过java -jar命令运行 Spring Boot 应用,而无需将应用部署到外部的 Web 服务器中,极大地提高了开发和部署的效率,尤其适合微服务架构的开发场景。同时,Spring Boot 的起步依赖(Starters)机制也为开发者带来了便利,它将常用的库和配置打包在一起,开发者只需添加一个依赖,就能引入与该依赖相关的所有库和配置,简化了项目的依赖管理 。

2.3 Netty:高性能网络通信的利刃

Netty 是一个基于 Java NIO 的高性能网络通信框架,广泛应用于网络编程领域。它采用异步事件驱动模型,所有的 I/O 操作都是异步的,当一个 I/O 操作被触发后,Netty 会立即返回,不会阻塞线程,从而提高了应用程序的并发处理能力。例如,在处理大量并发连接时,Netty 能够高效地管理这些连接,确保每个连接的请求都能得到及时处理。

Netty 的非阻塞 I/O 特性也是其一大优势。基于 Java NIO 技术,Netty 可以在一个线程中处理多个通道(Channel)的 I/O 操作,避免了传统阻塞 I/O 模型中线程被长时间占用的问题,显著提升了系统的吞吐量和性能。在实际应用中,像即时通讯、游戏服务器等对性能要求极高的场景,Netty 的非阻塞 I/O 特性能够发挥出巨大的优势。

此外,Netty 提供了丰富的 API 和工具类,使得开发者可以更加专注于业务逻辑的实现,而无需过多关注底层网络通信的细节。同时,它还支持多种协议,如 HTTP、WebSocket、TCP、UDP 等,满足了不同场景下的网络编程需求 。

三、Spring Boot 与 Netty 结合的优势

3.1 高性能

Netty 的异步非阻塞 I/O 模型和事件驱动机制使其在处理高并发网络请求时表现卓越。在传统的阻塞 I/O 模型中,当一个线程处理 I/O 操作时,它会被阻塞,直到 I/O 操作完成,这导致线程资源被浪费,无法处理其他请求。而 Netty 采用异步非阻塞 I/O,线程在发起 I/O 操作后,无需等待操作完成,可以立即处理其他任务,大大提高了线程的利用率和系统的并发处理能力。例如,在一个在线游戏服务器中,可能同时有数千个玩家连接,Netty 能够高效地处理这些玩家的请求,确保游戏的流畅运行 。

Netty 还提供了零拷贝技术,减少了数据在内存中的拷贝次数,提高了数据传输效率。传统的数据传输方式中,数据通常需要在用户空间和内核空间之间进行多次拷贝,这不仅消耗时间,还占用内存资源。Netty 通过使用 DirectBuffer、组合 Buffer 和 transferTo () 方法等技术,实现了数据的零拷贝传输,如在文件传输场景中,能够显著提升文件的传输速度 。

3.2 易用性

Spring Boot 的自动配置和起步依赖机制极大地简化了项目的搭建和配置过程。在集成 Netty 时,开发者只需添加相应的依赖,Spring Boot 就能自动配置好与 Netty 相关的环境,如线程池、通道等。以创建一个基于 Spring Boot 和 Netty 的简单网络应用为例,开发者只需在pom.xml文件中添加spring-boot-starter-netty依赖,Spring Boot 就会自动完成大部分的配置工作,开发者无需手动编写复杂的配置代码,降低了开发门槛和出错的概率 。

Spring Boot 的依赖注入和面向切面编程等特性也使得代码的组织和管理更加方便。开发者可以将 Netty 相关的业务逻辑封装成一个个的 Bean,通过依赖注入的方式在其他组件中使用,提高了代码的可维护性和可扩展性。在一个包含用户认证和消息处理的网络应用中,可以将用户认证逻辑和消息处理逻辑分别封装成独立的 Bean,通过依赖注入的方式在 Netty 的处理器中使用,使代码结构更加清晰 。

3.3 丰富的功能支持

Netty 支持多种协议,如 HTTP、WebSocket、TCP、UDP 等,这使得 Spring Boot 与 Netty 结合的应用能够满足不同场景的需求。在开发一个实时聊天应用时,可以使用 Netty 的 WebSocket 协议实现客户端与服务器之间的实时双向通信;而在开发一个文件传输应用时,则可以使用 Netty 的 TCP 协议确保数据传输的可靠性 。

Spring Boot 的生态系统提供了丰富的插件和工具,如监控、日志、安全等方面的支持。当与 Netty 结合时,这些功能可以无缝集成到网络应用中。例如,可以使用 Spring Boot Actuator 对基于 Netty 的应用进行健康检查、性能监控等操作,为应用的运维和管理提供了便利 。

四、Spring Boot 集成 Netty 的开发步骤

4.1 项目初始化

首先,我们需要创建一个新的 Spring Boot 项目。推荐使用 Spring Initializr,这是一个在线的项目初始化工具,能帮助我们快速生成 Spring Boot 项目的基本结构。打开浏览器,访问https://start.spring.io,在该页面中,我们可以进行一系列的项目配置。在 “Project Metadata” 部分,填写项目的基本信息,如 Group、Artifact、Name 等 。Group 通常是公司或组织的域名倒置,Artifact 是项目的名称,这两个字段将共同确定项目的 Maven 坐标。

在 “Dependencies” 部分,搜索并添加所需的依赖,如Spring Web依赖,它将为我们的项目提供 Web 开发的支持,包括 Spring MVC 和内嵌的 Tomcat 服务器等。完成配置后,点击 “Generate” 按钮,Spring Initializr 会生成一个压缩包,下载并解压该压缩包,然后使用 IDE(如 IntelliJ IDEA 或 Eclipse)导入项目,这样一个基本的 Spring Boot 项目就创建完成了 。

4.2 添加依赖

在项目的pom.xml文件中,添加 Netty 的依赖。如果使用的是 Maven 构建工具,可以在<dependencies>标签内添加如下依赖:

<dependency><groupId>io.netty</groupId><artifactId>netty - all</artifactId><version>4.1.68.Final</version>
</dependency>

 

这里的netty - all是一个聚合依赖,它包含了 Netty 的所有模块,方便我们在项目中使用。版本号可以根据实际情况进行调整,建议使用较新的稳定版本,以获取更好的性能和功能支持。添加完依赖后,Maven 会自动下载 Netty 及其相关的依赖库到本地仓库 。

4.3 编写 Netty 服务器

接下来,我们创建一个 Netty 服务器类。在src/main/java目录下,创建一个新的 Java 类,例如NettyServer。在这个类中,我们需要初始化 Netty 的相关组件。首先,创建两个EventLoopGroup,分别是bossGroup和workerGroup。bossGroup主要负责处理客户端的连接请求,workerGroup则用于处理已连接客户端的读写操作。

EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();

 

然后,创建一个ServerBootstrap对象,用于配置和启动 Netty 服务器。通过group方法将bossGroup和workerGroup设置到ServerBootstrap中,指定服务器使用的通道类型为NioServerSocketChannel,并设置一个ChannelInitializer,用于初始化每个新连接的通道。

ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new NettyServerHandler());}});

 

这里的NettyServerHandler是我们自定义的一个处理器类,用于处理客户端发送过来的消息。在NettyServerHandler类中,我们可以继承ChannelInboundHandlerAdapter类,并重写其中的channelRead方法,以实现对客户端消息的处理。

public class NettyServerHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf in = (ByteBuf) msg;try {System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8));} finally {ReferenceCountUtil.release(msg);}}
}

 

最后,在NettyServer类中,通过bind方法绑定服务器的端口,并调用sync方法等待绑定操作完成。在服务器关闭时,需要优雅地关闭bossGroup和workerGroup,释放资源。

try {ChannelFuture future = bootstrap.bind(8080).sync();future.channel().closeFuture().sync();
} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();
}

4.4 编写 Netty 客户端

创建一个 Netty 客户端类,如NettyClient。与服务器端类似,首先创建一个EventLoopGroup,用于处理客户端的 I/O 操作。

EventLoopGroup group = new NioEventLoopGroup();

然后,创建一个Bootstrap对象,用于配置和启动 Netty 客户端。通过group方法将EventLoopGroup设置到Bootstrap中,指定客户端使用的通道类型为NioSocketChannel,并设置一个ChannelInitializer,用于初始化客户端的通道。

Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new NettyClientHandler());}});

这里的NettyClientHandler是客户端的处理器类,用于处理从服务器端接收到的消息。在NettyClientHandler类中,继承ChannelInboundHandlerAdapter类,并重写channelActive方法,在客户端连接成功后向服务器发送消息;重写channelRead方法,处理从服务器接收到的消息。

public class NettyClientHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {ctx.writeAndFlush(Unpooled.copiedBuffer("Hello, Server!", CharsetUtil.UTF_8));}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf in = (ByteBuf) msg;try {System.out.println("Client received: " + in.toString(CharsetUtil.UTF_8));} finally {ReferenceCountUtil.release(msg);}}
}

 

最后,在NettyClient类中,通过connect方法连接到服务器,并调用sync方法等待连接操作完成。在客户端关闭时,同样需要优雅地关闭EventLoopGroup,释放资源。

try {ChannelFuture future = bootstrap.connect("localhost", 8080).sync();future.channel().closeFuture().sync();
} finally {group.shutdownGracefully();
}

4.5 在 Spring Boot 中启动 Netty 服务

为了在 Spring Boot 应用中启动 Netty 服务,我们可以使用CommandLineRunner接口。创建一个实现了CommandLineRunner接口的类,例如NettyServerRunner。在这个类中,通过依赖注入的方式获取NettyServer实例,并在run方法中调用NettyServer的启动方法。

 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class NettyServerRunner implements CommandLineRunner {@Autowiredprivate NettyServer nettyServer;@Overridepublic void run(String... args) throws Exception {nettyServer.start();}
}

 

另外,我们还可以使用 Spring 的生命周期注解,如@PostConstruct。在NettyServer类中,添加@PostConstruct注解到启动方法上,这样在 Spring 容器初始化完成后,该方法会自动被调用,从而启动 Netty 服务。

 
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;@Component
public class NettyServer {@PostConstructpublic void start() {// 启动Netty服务器的代码}
}

 

通过以上步骤,我们就完成了 Spring Boot 与 Netty 的集成,实现了一个简单的基于 Netty 的网络应用。在实际开发中,我们可以根据具体需求对 Netty 服务器和客户端进行进一步的扩展和优化,以满足不同场景下的业务需求 。

五、Spring Boot+Netty 的应用场景

5.1 实时聊天系统

在实时聊天系统中,Spring Boot 与 Netty 的结合发挥了巨大优势。Netty 的异步非阻塞 I/O 模型和事件驱动机制,能够高效地处理大量客户端的并发连接,确保消息的实时传输。当多个用户同时发送和接收消息时,Netty 可以快速地将消息分发给对应的客户端,实现即时通讯。通过 Netty 的编解码功能,可以对消息进行高效的序列化和反序列化处理,提高数据传输的效率 。

Spring Boot 则为聊天系统提供了便捷的后端服务支持。利用 Spring Boot 的自动配置和依赖注入,开发者可以轻松地集成数据库,用于存储用户信息、聊天记录等数据。同时,Spring Boot 的安全机制可以对用户进行认证和授权,保障聊天系统的安全性。例如,通过 Spring Security 框架,可以实现用户的登录验证和权限管理,防止非法用户访问聊天系统 。

5.2 数据流直播平台

对于数据流直播平台,实时性和低延迟是关键要求。Netty 的高性能网络通信能力能够满足这一需求,它可以快速地将直播数据传输给大量的观众。通过使用 Netty 的零拷贝技术和优化的网络传输算法,能够减少数据传输的延迟,确保观众能够实时观看直播内容 。

Spring Boot 在数据流直播平台中负责管理和调度各种服务。它可以集成消息队列,如 Kafka 或 RabbitMQ,用于处理直播过程中的消息传递,如观众的点赞、评论等操作。Spring Boot 还可以与云存储服务集成,如 AWS S3 或阿里云 OSS,用于存储直播视频文件,方便后续的回放和管理 。

5.3 在线游戏服务器

在线游戏服务器需要处理大量玩家的并发请求,并且对实时性要求极高。Spring Boot 与 Netty 的结合能够很好地满足这些需求。Netty 的异步非阻塞 I/O 模型和多线程处理能力,使得游戏服务器可以同时处理成千上万玩家的连接,并且能够快速响应玩家的操作,如移动、攻击、聊天等 。

利用 Netty 的协议定制功能,开发者可以根据游戏的需求自定义网络协议,提高游戏数据传输的效率和安全性。Spring Boot 则为游戏服务器提供了丰富的功能支持,如配置管理、日志记录、监控等。通过 Spring Boot Actuator,开发者可以实时监控游戏服务器的性能指标,如 CPU 使用率、内存使用率、玩家在线数量等,以便及时进行优化和调整 。

六、案例分析

6.1 案例背景介绍

假设我们正在为一家在线教育平台开发一个实时互动课堂系统。该系统需要支持大量学生同时在线上课,教师能够实时推送课程内容、进行直播讲解,学生可以随时提问、发表评论,并且系统要保证消息的即时传输和低延迟,以提供流畅的课堂体验。为了满足这些需求,我们决定采用 Spring Boot 与 Netty 相结合的技术方案 。

6.2 技术实现方案

在技术架构上,我们使用 Spring Boot 作为后端核心框架,负责处理业务逻辑、用户认证、与数据库交互等。利用 Spring Boot 的自动配置和起步依赖,快速搭建起项目的基础架构,并集成了 Spring Data JPA 用于数据库操作,Spring Security 实现用户认证和授权 。

Netty 则被用于构建高性能的网络通信层。通过 Netty 的 WebSocket 协议,实现了教师端和学生端之间的实时双向通信。在 Netty 服务器中,我们自定义了 ChannelHandler,用于处理接收到的消息,如将教师发送的课程内容广播给所有在线学生,将学生的提问和评论转发给教师等 。

为了优化性能,我们还采用了 Netty 的零拷贝技术,减少数据传输过程中的内存拷贝,提高数据传输效率。同时,通过合理配置 Netty 的线程池,确保在高并发情况下能够高效地处理大量的网络请求 。

6.3 效果展示

经过实际测试,该系统在性能方面表现出色。在同时有 500 名学生在线的情况下,消息的平均传输延迟低于 100 毫秒,能够满足实时互动课堂对即时性的要求。系统的吞吐量也达到了较高水平,能够稳定地处理大量的消息发送和接收请求 。

在实际使用中,教师和学生反馈良好。教师可以流畅地进行直播讲解,学生能够及时收到课程内容和回复,提问和评论也能迅速传达给教师,大大提升了在线课堂的互动性和教学效果,为在线教育平台的成功运营提供了有力支持 。

七、总结与展望

7.1 总结 Spring Boot+Netty 的优势和应用前景

Spring Boot 与 Netty 的结合,无疑是 Java 开发领域的一次强大创新。Spring Boot 凭借其自动配置、内嵌服务器和起步依赖等特性,极大地简化了项目的搭建与开发过程,让开发者能够专注于业务逻辑的实现。而 Netty 的异步非阻塞 I/O 模型、高性能以及丰富的协议支持,为构建高效、可靠的网络应用提供了坚实的基础。两者结合,在性能、易用性和功能丰富度上都展现出了显著的优势。

在性能方面,Netty 的异步非阻塞特性和零拷贝技术,使得系统能够在高并发场景下保持高效运行,大大提升了系统的吞吐量和响应速度。在实时聊天系统、在线游戏服务器等对性能要求极高的场景中,这种优势尤为明显。在易用性上,Spring Boot 的自动配置和依赖注入机制,与 Netty 的集成变得简单便捷,降低了开发成本和难度。开发者可以轻松地在 Spring Boot 项目中引入 Netty,快速构建出功能强大的网络应用 。

从应用前景来看,Spring Boot+Netty 的组合在众多领域都有着广阔的应用空间。在金融领域,可用于开发实时行情推送、交易系统等,确保金融数据的快速、准确传输;在物联网领域,能够实现设备与服务器之间的高效通信,满足海量设备连接和数据传输的需求;在工业互联网中,有助于构建实时监控和控制系统,实现生产过程的智能化管理 。

7.2 对未来发展的展望

展望未来,随着技术的不断发展,Spring Boot 和 Netty 也将持续演进。Spring Boot 有望进一步优化其自动配置功能,提供更多开箱即用的解决方案,与新兴技术如云计算、大数据的集成也将更加紧密,为开发者提供更强大的支持。Netty 则可能在性能优化、协议支持和功能扩展等方面不断突破,适应日益复杂的网络应用需求。

在应用拓展方面,随着 5G 技术的普及和物联网设备的大量增加,对高性能、低延迟网络通信的需求将愈发强烈。Spring Boot+Netty 的组合将在这些新兴领域发挥更大的作用,推动相关行业的快速发展。未来,我们还可能看到更多基于 Spring Boot+Netty 的开源项目和框架出现,进一步丰富和完善这一技术生态,为开发者提供更多的选择和便利。

相关文章:

Spring Boot 邂逅Netty:构建高性能网络应用的奇妙之旅

一、引言 在当今数字化时代&#xff0c;构建高效、可靠的网络应用是开发者面临的重要挑战。Spring Boot 作为一款强大的 Java 开发框架&#xff0c;以其快速开发、简洁配置和丰富的生态支持&#xff0c;深受广大开发者喜爱。而 Netty 作为高性能、异步的网络通信框架&#xff…...

简识JVM私有内存区域栈、数据结构

前记&#xff1a;JVM稀有内存区域栈包含&#xff1a;虚拟机栈、本地方法栈、程序计数器&#xff1b; 在JVM&#xff08;Java虚拟机&#xff09;中&#xff0c;私有内存区域栈主要指的是虚拟机栈&#xff08;VM Stack&#xff09;和本地方法栈&#xff08;Native Method Stack&…...

【C++基础】多线程并发场景下的同步方法

如果在多线程程序中对全局变量的访问没有进行适当的同步控制&#xff08;例如使用互斥锁、原子变量等&#xff09;&#xff0c;会导致多个线程同时访问和修改全局变量时发生竞态条件&#xff08;race condition&#xff09;。这种竞态条件可能会导致一系列不确定和严重的后果。…...

【优选算法】10----无重复字符的最长子串

---------------------------------------begin--------------------------------------- 题目解析&#xff1a; 看到这一类题目&#xff0c;有没有那种一眼就感觉时要用到滑动窗口的感觉&#xff0c;铁子们&#xff1f; 讲解算法原理&#xff1a; 方法一: 暴力解法&#xff…...

C语言程序设计十大排序—冒泡排序

文章目录 1.概念✅2.冒泡排序&#x1f388;3.代码实现✅3.1 直接写✨3.2 函数✨ 4.总结✅ 1.概念✅ 排序是数据处理的基本操作之一&#xff0c;每次算法竞赛都很多题目用到排序。排序算法是计算机科学中基础且常用的算法&#xff0c;排序后的数据更易于处理和查找。在计算机发展…...

26考研资料分享 百度网盘

基础班&#xff1a; 通过网盘分享的文件&#xff1a;2026【考研数学】等3个文件 链接:https://pan.baidu.com/s/1djzJiut1h0DH8WmrI05YHg?pwd1234 提取码:1234--来自百度网盘超级会员v3的分享 通过网盘分享的文件&#xff1a;01、2026【考研政治】 链接:https://pan.baidu.…...

C++ lambda表达式

目录 1.lambda表达式 1.1什么是Lambda表达式&#xff1f; 1.2Lambda表达式的语法 1.3捕捉列表 1.4函数对象与lambda表达式 1.lambda表达式 1.1什么是Lambda表达式&#xff1f; Lambda表达式是C11标准引入的一种匿名函数&#xff0c;它允许你在需要函数的地方直接编写代码…...

halo附件图片迁移到easyimage图床

前言 在使用 markdown 编写文章之后&#xff0c;markdown 内容中引用的图片都是图床的地址 部分文章是在 halo 没有使用图床前&#xff0c;就已经发布了的&#xff0c;这些图片都是直接存储在 halo 系统中的 需要将这些文章的图片全部迁移到图床上&#xff0c;这些文章的图片…...

Grafana

Grafana 是一款广泛使用的开源数据可视化与监控平台&#xff0c;通过与 Prometheus、InfluxDB、Elasticsearch 等多种数据源集成&#xff0c;提供强大的监控、数据展示和告警功能。其告警体系在及时通知系统异常、保障业务稳定性方面起到关键作用。 Grafana 告警体系概述 Graf…...

前端性能优化:HMR热更新和预获取加载

最近发现项目开发&#xff0c;有点加载快&#xff0c;有点却是卡机式&#xff0c;甚至刷新导致白屏情况。于是&#xff0c;我找开发和性能优化的方法&#xff0c;找到下面几种。 本文将深入探讨 预获取&#xff08;Prefetch&#xff09;、动态导入&#xff08;Dynamic Import&…...

OpenCV相机标定与3D重建(66)对立体匹配生成的视差图(disparity map)进行验证的函数validateDisparity()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 使用左右检查来验证视差。矩阵 “cost” 应该由立体对应算法计算。 cv::validateDisparity 函数是 OpenCV 库中用于对立体匹配生成的视差图&…...

git reset (取消暂存,保留工作区修改)

出现这种情况的背景&#xff1a;我不小心把node_modules文件添加到暂存区了&#xff0c;由于文件过大&#xff0c;导致不能提交&#xff0c;所以我想恢复之前的状态&#xff0c;但又不想把修改的代码恢复为之前的状态&#xff0c;所以使用这个命令可以只恢复暂存区的状态&#…...

【论文+源码】diffuseq使用扩散模型和diffuseq-v2的序列文本生成序列,并且桥接离散和连续的文本空间,用于加速SEQ2SEQ扩散模型。

这篇论文介绍了一种名为DIFFUSEQ的新型扩散模型&#xff0c;专门针对序列到序列&#xff08;SEQ2SEQ&#xff09;文本生成任务进行设计。尽管扩散模型在视觉和音频等连续信号领域取得了成功&#xff0c;但在自然语言处理特别是条件生成方面的适应仍然未被广泛探索。通过广泛的评…...

考研机试题:打印日期

描述 给出年分m和一年中的第n天&#xff0c;算出第n天是几月几号。 输入描述: 输入包括两个整数y(1<y<3000)&#xff0c;n(1<n<366)。 输出描述: 可能有多组测试数据&#xff0c;对于每组数据&#xff0c; 按 yyyy-mm-dd的格式将输入中对应的日期打印出来。 …...

Ubuntu 20.04 x64下 编译安装ffmpeg

试验的ffmpeg版本 4.1.3 本文使用的config命令 ./configure --prefixhost --enable-shared --disable-static --disable-doc --enable-postproc --enable-gpl --enable-swscale --enable-nonfree --enable-libfdk-aac --enable-decoderh264 --enable-libx265 --enable-libx…...

springboot使用ssl连接elasticsearch

使用es时ssl证书报错 unable to find valid certification path to requested target 1.依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>2…...

虚拟头节点和双指针解决链表问题(合并,与分解操作,力扣题目为例)

Problem: 21. 合并两个有序链表 Problem: 86. 分隔链表 文章目录 总览说明题目描述思路复杂度Code总结分析 总览说明 在解决链表相关的算法题目时较多使用到的技巧就是虚拟头节点、双指针&#xff0c;而题目往往都会涉及到对链表的分解、合并操作&#xff0c;本文选择两个题目将…...

JavaScript系列(38)-- WebRTC技术详解

JavaScript WebRTC技术详解 &#x1f3a5; 今天&#xff0c;让我们深入了解WebRTC&#xff08;Web Real-Time Communication&#xff09;技术&#xff0c;这是一种支持网页浏览器进行实时语音对话或视频对话的技术。 WebRTC基础概念 &#x1f31f; &#x1f4a1; 小知识&…...

分布式理解

分布式 如何理解分布式 狭义的分布是指&#xff0c;指多台PC在地理位置上分布在不同的地方。 分布式系统 分布式系**统&#xff1a;**多个能独立运行的计算机&#xff08;称为结点&#xff09;组成。各个结点利用计算机网络进行信息传递&#xff0c;从而实现共同的“目标或者任…...

JVM学习指南(48)-JVM即时编译

文章目录 即时编译(Just-In-Time Compilation, JIT)概述为什么JVM需要即时编译?即时编译与传统的静态编译的区别JVM中的即时编译器HotSpot VM中的C1和C2编译器编译器的作用和位置即时编译的工作流程代码的加载和解释执行热点代码检测编译优化编译优化技术公共子表达式消除循…...

python http调用视觉模型moondream

目录 一、什么是moondream 二、资源地址 三、封装了http进行接口请求 四、代码解析 解释 可能的改进 一、什么是moondream Moondream 是一个针对视觉生成任务的深度学习模型,专注于图像理解和生成,包括图像标注(captioning)、问题回答(Visual Question Answering,…...

【竞技宝】DOTA2:NAVI junior被ESL取消参赛资格

北京时间1月24日,DOTA2目前有多个赛事的预选赛正在如火如荼的进行之中,其中ESLOne罗利站的预选赛已经结束,参赛正赛的队伍也已经全部产生。除了因EPT积分而拿到直邀资格的PARI、BB、falcons、liquid之外,tundra、NAVI junior、spirit、nigma、XG、talon、SR、HEROIC也通过各赛区…...

Java 在包管理与模块化中的优势:与其他开发语言的比较

在开发复杂的、规模庞大的软件系统时&#xff0c;包管理和模块化设计起着至关重要的作用。它们不仅决定了代码的组织和可维护性&#xff0c;还直接影响到团队协作效率、扩展性和性能。在众多编程语言中&#xff0c;Java 凭借其成熟的生态系统、强类型系统和标准化的包管理机制&…...

如何用数据编织、数据虚拟化与SQL-on-Hadoop打造实时、可扩展兼容的数据仓库?

在大数据技术迅猛发展的背景下&#xff0c;许多人认为传统数据仓库已过时。然而&#xff0c;这种观点忽略了数据仓库的核心价值&#xff1a;统一的数据视图、强大的业务逻辑支撑以及丰富的数据分析能力。在企业数据架构转型中&#xff0c;数据仓库不仅未被淘汰&#xff0c;反而…...

MVCC底层原理实现

MVCC的实现原理 了解实现原理之前&#xff0c;先理解下面几个组件的内容 1、 当前读和快照读 先普及一下什么是当前读和快照读。 当前读&#xff1a;读取数据的最新版本&#xff0c;并对数据进行加锁。 例如&#xff1a;insert、update、delete、select for update、 sele…...

【Nacos】负载均衡

目录 前言 一、服务下线二、权重配置三、同一个集群优先访问四、环境隔离 前言 我们的生产环境相对是比较恶劣的&#xff0c;我们需要对服务的流量进行更加精细的控制.Nacos支持多种负载均衡策略&#xff0c;包括配置权重&#xff0c;同机房&#xff0c;同地域&#xff0c;同环…...

Batch Normalization学习笔记

文章目录 一、为何引入 Batch Normalization二、具体步骤1、训练阶段2、预测阶段 三、关键代码实现四、补充五、参考文献 一、为何引入 Batch Normalization 现在主流的卷积神经网络几乎都使用了批量归一化&#xff08;Batch Normalization&#xff0c;BN&#xff09;1&#xf…...

PIC单片机HEX文件格式分析

在调试PIC单片机在bootloader程序时&#xff0c;需要将hex文件转换为bin文件&#xff0c;在转换之前先了解一下hex文件中数据是如何定义的。 直接打开一个LED灯闪烁的程序生成的hex文件&#xff0c;芯片型号为PIC18F46K80 可以看到每条数据都是由6部分组成的&#xff0c;下面分…...

【unity游戏开发之InputSystem——07】InputSystem+UGUI配合使用(基于unity6开发介绍)

文章目录 一、InputSystem+UGUI配合使用1、官方文档参考2、切换到新的输入模块二、UGUI中的新输入系统输入模块参数相关1、Send Pointer Hover To Parent2、Move Repeat Delay3、Move Repeat Rate4、XR Tracking Origin5、Deselect On Background CLick6、Pointer Behavior7、S…...

RocketMQ 的 Topic 和消息队列MessageQueue信息,是怎么分布到Broker的?怎么负载均衡到Broker的?

目录 1. Topic 和 MessageQueue 的基本概念 1.1 Topic 1.2 MessageQueue 2. Topic 和 MessageQueue 的分布 2.1 Topic 的创建 2.2 MessageQueue 分配到 Broker 2.3 分布规则 3. 负载均衡机制 3.1 Producer 的负载均衡 3.2 Consumer 的负载均衡 3.3 Broker 的负载均衡…...

Qt简单迷宫游戏

目录 你将学到你将准备你将改变你将设计你将编程开始界面游玩界面胜利界面其它bug修复 你可扩展下一篇博客要说的东西 你将学到 Qt中QKeySequence对象的基本创建Qt中QShortcut对象的基本应用Qt中QSoundEffect对象的基本应用 你将准备 在开始制作Qt简单迷宫游戏之前&#xff…...

Webrtc (1) - Windows 编译

最近项目上遇到webrtc wgc 的几个test case无法通过&#xff0c;与webrtc人员沟通后决定要自行修复一下(因为他们不想管…) 参考文档 https://webrtc.org/support/contributinghttps://chromium.googlesource.com/chromium/src//main/docs/#checking-out-and-building 以上两…...

深圳大学-智能网络与计算-实验一:RFID原理与读写操作

实验目的与要求 掌握超高频RFID标签的寻卡操作。掌握超高频RFID标签的读写操作。掌握超高频RFID标签多张卡读取时的防冲突机制。 方法&#xff0c;步骤 软硬件的连接与设置超高频RFID寻卡操作超高频RFID防冲突机制超高频RFID读写卡操作 实验过程及内容 一&#xff0e;软硬…...

文献引用指南ChatGPT提示词分享

文献引用指南 在学术写作中&#xff0c;准确引用是至关重要的环节。它不仅能够为您的研究提供坚实的学术基础&#xff0c;还能确保您尊重并认可他人的学术成果&#xff0c;从而有效避免抄袭的问题。而ChatGPT在这一方面同样能够为您提供有力的支持。借助ChatGPT&#xff0c;您…...

什么是计算机应用基础知识

计算机应用基础知识是指学习和掌握计算机的基本理论、硬件、软件、网络和应用技能的基础内容。它是为使用计算机进行日常工作、学习和解决实际问题打下的基础。计算机应用基础知识涉及多个领域,主要包括以下几个方面: 一、计算机硬件基础 计算机硬件组成:了解计算机的基本组…...

SpringBoot集成Flink-CDC,实现对数据库数据的监听

一、什么是 CDC &#xff1f; CDC 是Change Data Capture&#xff08;变更数据获取&#xff09;的简称。 核心思想是&#xff0c;监测并捕获数据库的变动&#xff08;包括数据或数据表的插入、 更新以及删除等&#xff09;&#xff0c;将这些变更按发生的顺序完整记录下来&…...

微信小程序云开发服务端存储API 从云存储空间删除文件

deleteFile 从云存储空间删除文件 const cloud require(wx-server-sdk)exports.main async (event, context) > {const fileIDs [xxx, xxx]const result await cloud.deleteFile({fileList: fileIDs,})return result.fileList }写的资式如有不对&#xff0c;请各位大神多…...

[操作系统] 深入进程地址空间

程序地址空间回顾 在C语言学习的时&#xff0c;对程序的函数、变量、代码等数据的存储有一个大致的轮廓。在语言层面上存储的地方叫做程序地址空间&#xff0c;不同类型的数据有着不同的存储地址。 下图为程序地址空间的存储分布和和特性&#xff1a; 使用以下代码来验证一下…...

gitlab处理空文件夹的提交或空文件夹提交失败

问题描述 厂家发给了我一个压缩包文件&#xff0c;压缩包解压之后本地编译没问题&#xff1b;推送到gitlab之后&#xff0c;再编译就报错了&#xff1b; 问题原因 经过分析之后发现&#xff0c;压缩包解压之后存在很多空文件夹&#xff1b;但是gitlab推送的时候&#xff0c;…...

C++ —— 智能指针 unique_ptr (上)

C —— 智能指针 unique_ptr &#xff08;上&#xff09; 普通指针的不足普通指针的释放智能指针智能指针 unique_ptr智能指针初始化错误用法get()方法返回裸指针智能指针不支持指针的运算&#xff08;、-、、- -&#xff09; 普通指针的不足 new和new [] 的内存需要用delete和…...

ruoyi-vue-pro集成magic-api(图文代码)

目录 前言1. 配置依赖2. 集成登录3. 成功展示前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 原先写过简单的集成:了解 magic-api的基本用法 附实战代码 magic-api相关文档推荐阅读:接口鉴权 相关的Java代码推荐阅读: java框架 零基础从入门到精…...

【线上问题定位处理】及【性能优化】系列文章

目录 性能优化 性能优化 九大服务架构性能优化方式 如何进行GC调优 如何排查线上系统出现的Full GC MySQL - 性能优化 MySQL - 分库分表 大数据查询的处理方案 MySQL优化手段有哪些 服务CPU100%问题如何快速定位? 服务内存OOM问题如何快速定位? JVM调优6大步骤 线…...

如何解压rar格式文件?8种方法(Win/Mac/手机/网页端)

RAR 文件是一种常见的压缩文件格式&#xff0c;由尤金・罗谢尔&#xff08;Eugene Roshal&#xff09;开发&#xff0c;因其扩展名 “rar” 而得名。它通过特定算法将一个或多个文件、文件夹进行压缩&#xff0c;大幅减小存储空间&#xff0c;方便数据传输与备份。然而&#xf…...

GORM 支持的数据库解析

GORM 是一个流行的 Go 语言 ORM&#xff08;对象关系映射&#xff09;库&#xff0c;它简化了 Go 与数据库之间的交互。作为一款功能强大的库&#xff0c;GORM 支持多种主流关系型数据库&#xff0c;满足不同开发场景下的需求。本文将探讨 GORM 支持的主要数据库及其特点&#…...

分布式光纤应变监测是一种高精度、分布式的监测技术

一、土木工程领域 桥梁结构健康监测 主跨应变监测&#xff1a;在大跨度桥梁的主跨部分&#xff0c;如悬索桥的主缆、斜拉桥的斜拉索和主梁&#xff0c;分布式光纤应变传感器可以沿着这些关键结构部件进行铺设。通过实时监测应变情况&#xff0c;能够精确捕捉到车辆荷载、风荷…...

如何在oracle关闭情况下如何修改spfile的参数

如何在oracle关闭情况下如何修改spfile的参数 一、问题背景二、处理方案 一、问题背景 在ORACLE数据库启动状态下通过下列代码修改了最大连接数 alter system set processes2000 scopespfile sid*;关闭了数据库再重新启动提示如下报错&#xff1a; ORA-00838: Specified valu…...

[ Spring ] Spring Cloud Gateway 2025 Comprehensive Overview

文章目录 Spring Gateway ArchitectureProject Level DependencyService CenterService ProviderGateway ServiceLaunch All Service Spring Gateway Architecture Service Center : register and find service providerService Provider : programs that provide actual serv…...

软考信安27~Windows操作系统安全相关

1、Windows账户与组管理 1.1、用户账户查看 whoami #查看当前登录的用户名称 whoami /all #查看当前系统的用户名和组信息,以及SID whoami /user #查看当前用户的SID net user #查看系统中包含哪些用户 wmic useraccount get name,sid #查看…...

2025年数学建模美赛 A题分析(3)楼梯使用方向偏好模型

2025年数学建模美赛 A题分析&#xff08;1&#xff09;Testing Time: The Constant Wear On Stairs 2025年数学建模美赛 A题分析&#xff08;2&#xff09;楼梯磨损分析模型 2025年数学建模美赛 A题分析&#xff08;3&#xff09;楼梯使用方向偏好模型 2025年数学建模美赛 A题分…...

Spring整合Mybatis、junit纯注解

如何创建一个Spring项目 错误问题 不知道什么原因&#xff0c;大概是依赖版本不兼容、java版本不对的问题&#xff0c;折磨了好久就是搞不成。 主要原因看pom.xml配置 pom.xml配置 java版本 由于是跟着22年黑马视频做的&#xff0c;java版本换成了jdk-11&#xff0c;用21以…...