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 框架中用于配置和启动客户端或服务器端网络应用程序的重要组件 主要功能
|
EventLoopGroup | EventLoopGroup扩展了Reactor线程的功能,用一个线程池实现了多个Reactor线程负责的工作,充分利用了CPU的并发处理能力。
Boss EventLoopGroup监听客户端的连接,接受客户端的连接后将之后的IO处理及数据传输都交给Work EventLoopGroup。 主要功能
|
Channel | netty中的channel提供的功能类似NIO中的SocketChannel,是数据传输的通道。 主要功能
|
ByteBuf | ByteBuf 是 Netty 中用于处理字节缓冲区的重要组件,它提供了比 Java 原生 ByteBuffer 更强大、更灵活的功能 主要方法
内存分配方式
|
ChannelFuture | ChannelFuture 是 Netty 框架中用于处理异步 I/O 操作结果的接口 常用方法
|
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:构建高性能网络应用的奇妙之旅
一、引言 在当今数字化时代,构建高效、可靠的网络应用是开发者面临的重要挑战。Spring Boot 作为一款强大的 Java 开发框架,以其快速开发、简洁配置和丰富的生态支持,深受广大开发者喜爱。而 Netty 作为高性能、异步的网络通信框架ÿ…...

【云安全】云原生-Docker(五)容器逃逸之漏洞利用
漏洞利用逃逸 通过漏洞利用实现逃逸,主要分为以下两种方式: 1、操作系统层面的内核漏洞 这是利用宿主机操作系统内核中的安全漏洞,直接突破容器的隔离机制,获得宿主机的权限。 攻击原理:容器本质上是通过 Linux 的…...

九、CSS工程化方案
一、PostCSS介绍 二、PostCSS插件的使用 项目安装 - npm install postcss-cli 全局安装 - npm install postcss-cli -g postcss-cli地址:GitHub - postcss/postcss-cli: CLI for postcss postcss地址:GitHub - postcss/postcss: Transforming styles…...

gradle创建springboot单项目和多模块项目
文章目录 gradle创建springboot项目gradle多模块项目创建 gradle创建springboot项目 适用IDEA很简单,如下图 gradle多模块项目创建 首选创建父项目,然后删除无用内容至下图 选择父项目目录,右键选择模块,创建子项目(…...

Vue实现div滚动,并且支持top动态滚动
如果你知道距离目标 div 顶部的像素值,并希望通过传入 top 参数来实现滚动到对应区域,可以使用 window.scrollTo 方法。 编写滚动方法 const scrollToDiv (targetDiv, top) > {if (targetDiv) {top top * targetDiv.value.scrollHeight / data.he…...

Elasticsearch 中,分片(Shards)数量上限?副本的数量?
概念 ElasticSearch高可用集群架构实战 分片数量1 在 Elasticsearch 中,分片(Shards)是数据存储和索引的基本单位。创建分片时需要考虑多个因素,包括集群的配置、硬件资源(如磁盘空间、内存等)以及性能要…...

Unity入门1
安装之后无法获得许可证,可以考虑重装 新建项目 单击空白处生成脚本 双击c#文件 会自动打开vstudio 检查引用 如果没有引用,重开vstu,或者重新加载项目 hierarchy层级 scenes场景 assets资产 inspector督察 icon图标 资源链接&…...

网络模型简介:OSI七层模型与TCP/IP模型
计算机网络是现代信息社会的基石,而网络通信的基础在于理解网络模型。网络模型是对通信过程的抽象,它帮助我们理解数据从源到目的地的传输过程。常见的网络模型有 OSI 七层模型 和 TCP/IP 模型,这两种模型在理论和实践中都起着重要作用。 一、…...

软件测试压力太大了怎么办?
本文其实是知乎上针对一个问题的回答: 目前在做软件测试,主要负责的是手机端的项目测试,项目迭代很快,每次上线前验正式都会发现一些之前验测试包时候没有发现的问题,压力太大了,应该怎么调整 看过我之前其…...

微信小程序-点餐(美食屋)02开发实践
目录 概要 整体架构流程 (一)用户注册与登录 (二)菜品浏览与点餐 (三)订单管理 (四)后台管理 部分代码展示 1.index.wxml 2.list.wxml 3.checkout.wxml 4.detail.wxml 小结优点 概要…...

转换算术表达式
文章目录 构造二叉树表示的算术表达式:按先序次序输入二叉树中结点的值(操作数及运算符均以一位字符表示,注意转换), #字符表示空树,如上图的算术表达式 输入2##*3##4## 输入格式 第一行输入表示要计算的算术表达式的二叉树结点的…...

99.17 金融难点通俗解释:归母净利润
目录 0. 承前1. 简述2. 比喻:小明家的小卖部2.1 第一步:计算收到的所有钱2.2 第二步:减去各种支出2.3 第三步:计算能带回家的钱 3. 生活中的例子3.1 好的经营情况3.2 一般的经营情况3.3 不好的经营情况 4. 小朋友要注意4.1 为什么…...

【Flutter】旋转元素(Transform、RotatedBox )
这里写自定义目录标题 Transform旋转元素可以改变宽高约束的旋转 - RotatedBox Transform旋转元素 说明:Transform旋转操作改变了元素的方向,但并没有改变它的布局约束。因此,虽然视觉上元素看起来是旋转了,但它仍然遵循原始的宽…...

MYSQL学习笔记(六):聚合函数、sql语句执行原理简要分析
前言: 学习和使用数据库可以说是程序员必须具备能力,这里将更新关于MYSQL的使用讲解,大概应该会更新30篇,涵盖入门、进阶、高级(一些原理分析);这一篇是内容较少,主要讲解:聚合函数和简要介绍sql语句执行过…...

thinkphp6+swoole使用rabbitMq队列
安装think-swoole安装 composer require php-amqplib/php-amqplib,以支持rabbitMq使用安装rabbitMq延迟队列插件 安装 rabbitmq_delayed_message_exchange 插件,按照以下步骤操作: 下载插件:https://github.com/rabbitmq/rabbitmq-delayed-…...

大模型开发 | RAG在实际开发中可能遇到的坑
近年来,大语言模型 (LLM) 的飞速发展令人瞩目,它们在各个领域展现出强大的应用潜力。然而,LLM 也存在一些固有的局限性,例如知识更新滞后、信息编造 (幻觉) 等问题。为了克服这些挑战,检索增强生成 (Retrieval-Augment…...

mybatis是什么?有什么作用?mybatis的简单使用
mybatis是什么? MyBatis 是一个持久层框架。 有什么作用? 简化了对数据库数据的操作。 如何简化数据操作的? MyBatis 通过提供 SQL 映射、动态 SQL、结果映射、事务管理等功能,我们直接去用就可以了。 怎么使用?&…...

求平均年龄(信息学奥赛一本通-1059)
【题目描述】 班上有学生若干名,给出每名学生的年龄(整数),求班上所有学生的平均年龄,保留到小数点后两位。 【输入】 第一行有一个整数n(1≤n≤100),表示学生的人数。其后n行每行有…...

CY T 4 BB 5 CEB Q 1 A EE GS MCAL配置 - MCU组件
1、ResourceM 配置 选择芯片信号: 2、MCU 配置 2.1 General配置 1) McuDevErrorDetect: - 启用或禁用MCU驱动程序模块的开发错误通知功能。 - 注意:采用DET错误检测机制作为安全机制(故障检测)时,不能禁用开发错误检测。2) McuGetRamStateApi - enable/disable th…...

10 Hyperledger Fabric 介绍
简介 HypeLedger(超级账本)是由Linux基金会2015年创建的首个面向企业应用场景的开源分布式账本平台。 HypeLedger Fabric是HypeLedger种的区块链项目之一HypeLedger Fabric引入权限管理在架构设计上支持可插拔、可扩展是首个面向联盟链场景的开源项目 …...

Word 中实现方框内点击自动打 √ ☑
注: 本文为 “Word 中方框内点击打 √ ☑ / 打 ☒” 相关文章合辑。 对第一篇增加了打叉部分,第二篇为第一篇中方法 5 “控件” 实现的详解。 在 Word 方框内打 √ 的 6 种技巧 2020-03-09 12:38 使用 Word 制作一些调查表、检查表等,通常…...

噪声算法 纹理
噪声是一种程序生成的随机或伪随机数据,在图形学中常用来创建各种自然现象和复杂纹理效果。 它的本质是一种由数学算法公式生成的有规则性或可控的随机数据。 通过噪声算法生成的随机数据具有以下特点: 随机性:噪声数据本质上是随机的&#…...

hexo + Butterfly搭建博客
Hexo是一个基于Node.js的静态网站生成器,主要用于快速搭建博客和个人网站。它使用Markdown语法编写文章,能够迅速生成静态页面并部署到服务器上。 配置node 使用nvm安装node(v16.13.2)后配置镜像 安装并使用node: nvm install 16.13.2 n…...

05.KNN算法总结
KNN算法总结 1 k近邻算法优缺点汇总 优点: 简单有效重新训练的代价低适合类域交叉样本 KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适…...

CentOS 7 搭建lsyncd实现文件实时同步 —— 筑梦之路
在 CentOS 7 上搭建 lsyncd(Live Syncing Daemon)以实现文件的实时同步,可以按照以下步骤进行操作。lsyncd 是一个基于 inotify 的轻量级实时同步工具,支持本地和远程同步。以下是详细的安装和配置步骤: 1. 系统准备 …...

java定时任务备份数据库
文章目录 前言一、定时任务备份二、分享两个windows运行项目脚本总结 前言 数据库备份 程序中数据库备份可以有效避免因为意外,导致数据丢失,因此数据备份显得尤为重要。 一、定时任务备份 定时任务类,要在配置类或启动类开启 EnableScheduling Data Sl4j Servic…...

Vue.js 传递路由参数和查询参数
Vue.js 传递路由参数和查询参数 在 Vue.js 开发中,Vue Router 提供了灵活的方式来处理路由参数和查询参数,使得组件能够根据不同的路径或查询条件渲染相应的内容。 路由参数 路由参数(也称为路径参数)是 URL 路径的一部分&…...

2025数学建模美赛|F题成品论文
国家安全政策与网络安全 摘要 随着互联网技术的迅猛发展,网络犯罪问题已成为全球网络安全中的重要研究课题,且网络犯罪的形式和影响日益复杂和严重。本文针对网络犯罪中的问题,基于多元回归分析和差异中的差异(DiD)思…...

私有包上传maven私有仓库nexus-2.9.2
一、上传 二、获取相应文件 三、最后修改自己的pom文件...

企业信息化4:免费开源的财务管理系统
前言: 一个完整的财务管理系统不局限于传统的记账和核算工具,而是一整套包含了公司财务战略规划制订、编制各种财务计划、预算管理、资金管理、资产管理、税务管理的完整解决方案,从而实现对公司整体经营状况进行财务分析并定期汇报ÿ…...