Spring WebFlux 高级实战(3-2)

1、SpringBoot 使用

1.1、Spring Core 中的响应式

        Spring 生态系统的核心模块是Spring Core 模块。Spring 5.x 引入对响应式流和响应式库的原生支持,其中,响应式库包含RxJava 1/2 和Project Reactor 3。

1.1.1、响应式类型转换支持

        为了支持响应式流规范所进行的最全面的改进之一是引入了 ReactiveAdapter 和 ReactiveAdapterRegistry 。ReactiveAdapter 类为响应式类型转换提供了两种基本方法,用于将任何类型转换为 Publisher<T> 并将其转换回 Object 。如以下源码所示:

org.springframework.core.ReactiveAdapter#toPublisher

org.springframework.core.ReactiveAdapter#fromPublisher

        如,为了提供对RxJava 2 中的Maybe 响应式类型的转换,我们可以通过以下方式创建自己的 ReactiveAdapter:

/**
* 适配器的构造器,包含了异步类型或响应式类型与Reactive Streams Publisher之间的相互转换。
*
* @param descriptor 响应式类型描述符
* @param toPublisherFunction 转换到Publisher的适配器
* @param fromPublisherFunction 从Publisher转换的适配器
*/
public MayBeReactiveAdapter(ReactiveTypeDescriptor descriptor,Function<Object, Publisher<?>>toPublisherFunction,Function<Publisher<?>, Object>fromPublisherFunction) {super(descriptor, toPublisherFunction, fromPublisherFunction);
}public MayBeReactiveAdapter() {super(ReactiveTypeDescriptor.singleOptionalValue(Maybe.class,Maybe::empty),rawMaybe -> ((Maybe<?>) rawMaybe).toFlowable(),publisher -> Flowable.fromPublisher(publisher).singleElement());
}

        上面实例中,扩展了默认的 ReactiveAdapter 并提供了一个自定义实现。父构造函数的第一个参数是 ReactiveTypeDescriptor 实例的定义。ReactiveTypeDescriptor 提供了有关 ReactiveAdapter 中使用的响应式类型的信息。父构造函数需要定义转换函数,而该函数将原始对象( Maybe )转换为 Publisher 并将任何 Publisher 转换回 Maybe 。

        为简化交互, ReactiveAdapterRegistry 使我们能将 ReactiveAdapter 的实例保存在一个位置并提供对它们的通用访问。如以下代码所示:

ReactiveAdapterRegistry.getSharedInstance().registerReactiveType(ReactiveTypeDescriptor.singleOptionalValue(Maybe.class,Maybe::empty),rawMaybe -> ((Maybe < ? > ) rawMaybe).toFlowable(),publisher -> Flowable.fromPublisher(publisher).singleElement()
);// 后续使用的时候直接通过共享实例访问
ReactiveAdapter maybeAdapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(Maybe.class);

        如代码所示,ReactiveAdapterRegistry 表示针对不同响应式类型的ReactiveAdapter实例的公共池。同时,ReactiveAdapterRegistry 提供了一个单例实例,该实例既可以在框架内的许多地方使用,也可以在开发的应用程序中使用。

1.1.2、响应式IO

        Spring Core 模块在 byte 缓冲区实例上引入了一个称为 DataBuffer 的抽象。之所以避免使用 java.nio.ByteBuffer ,主要是为了提供一个既可以支持不同字节缓冲区,又不需要在它们之间进行任何额外的转换的抽象。

        例如,为了将 io.netty.buffer.ByteBuf 转换为 ByteBuffer ,必须访问所存储的字节,而这些字节可能需要从堆外空间被拉入到堆中。这可能破坏Netty 提供的高效内存使用和缓冲区回收(重用相同的字节缓冲区)。

        Spring DataBuffer 提供特定实现的抽象,能以通用方式使用底层实现。DataBuffer 的 PooledDataBuffer 子接口,还启用了引用计数功能,并支持开箱即用的高效内存管理。

        此外,Spring Core 的第五版引入了 DataBufferUtils 类,能以响应式流的形式与I/O 进行交互(与网络、资源、文件等交互)。例如,可以基于背压支持并通过以下响应式的方式读取文件内容:

Flux<DataBuffer> reactiveHamlet = DataBufferUtils.read(new DefaultResourceLoader().getResource("Java入门到回家.txt"),new DefaultDataBufferFactory(),1024
);

        DataBufferUtils.read 返回一个 DataBuffer 实例的 Flux 。因此,可以使用 Reactor 的所有功能读取文件内容。最后,与Spring Core 中响应式相关的最后一个意义重大且不可或缺的特性是响应式编解码器(reactive codecs)。响应式编解码器提供了一种将 DataBuffer 实例流 和 对象流 进行相互转换的简便方式。Encoder 和 Decoder 接口即用于此目的,并提供以下用于编码/解码数据流的API:

interface Encoder<T> {Flux<DataBuffer> encode(Publisher<? extends T> inputStream,DataBufferFactory bufferFactory,ResolvableType elementType,@Nullable MimeType mimeType,@Nullable Map<String, Object> hints);
}interface Decoder<T> {Flux<T> decode(Publisher<DataBuffer> inputStream,ResolvableType elementType,@Nullable MimeType mimeType,@Nullable Map<String, Object> hints);Mono<T> decodeToMono(Publisher<DataBuffer> inputStream,ResolvableType elementType,@Nullable MimeType mimeType,@Nullable Map < String, Object > hints);
}

        两个接口都与响应式流中的 Publisher 一起运行,并能将 DataBuffer 实例流 编码/解码 为对象。它以非阻塞的方式,将序列化数据转换为java对象,将java对象序列化为序列化数据。

        这种编码/解码数据的方式可以减少处理延迟,这是因为响应式流在本质上支持独立的元素处理,而不必等到最后一个字节才开始解码整个数据集。

1.2、响应式 Web

        Spring Boot 2 引入了 WebFlux,支持高吞吐量、低延迟。Spring WebFlux建立在 响应式流适配器 之上,可以与 Netty 和 Undertow 以及基于 Servlet 3.1 的传统服务器等集成。Spring WebFlux 作为非阻塞的基础,将响应式流作为业务逻辑代码和服务器交互的中心抽象。

        注意,Servlet API 3.1 的适配器提供了与Web MVC 适配器不同的纯异步和非阻塞集成。Spring Web MVC 模块也支持Servlet API 4.0,后者支持HTTP/2。

        Spring WebFlux 将 Project Reactor 3 作为一等公民并广泛使用。响应式编程可以开箱即用,还可以在 Netty 上运行Web 应用程序。Spring WebFlux 模块提供内置的背压支持,可以确保 I/O 不会变得不堪重负。Spring WebFlux 的 WebClient 类,实现非阻塞的客户端交互。

        旧Web MVC 模块还获得了对响应式流的一些支持。从框架的第五版开始,Servlet API 3.1 成为 Web MVC 模块的基线。意味着 Web MVC 现在支持Servlet 规范提出的非阻塞I/O。Web MVC 模块的设计在适当级别的非阻塞 I/O 方面没有太大变化

        尽管如此,Servlet 3.0 的异步行为已经正确实现了一段时间。Spring Web MVC 为ResponseBodyEmitterReturnValueHandler 类提供了升级。

        由于Publisher 类可能被视为无限的事件流,因此在不破坏 Web MVC 模块的整个基础结构的情况下,Emitter 处理程序是放置响应式处理逻辑的适当位置。为此,Web MVC 模块引入了ReactiveTypeHandler 类,它负责正确处理 Flux 和 Mono 等响应式类型。为了在客户端获得非阻塞行为,除了支持服务器端响应式类型的变更,还可以使用 WebFlux 模块所提供的 WebClient 。

        Spring Boot 可以提供基于类路径中可用类的复杂环境管理行为。因此,通过提供WebMVC(spring-boot-starter-web)模块以及 WebFlux,我们可以从 WebFlux 模块获得 Web MVC 环境和非阻塞响应式 WebClient 。最后,当将这两个模块作为响应式管道进行比较时,得到的结构如下图所示:

        在 Web MVC 或 WebFlux 这两种用法中,得到了几乎相同的基于响应式流的编程模型。这两个模块之间的显著差异之一是 Web MVC 需要在与源自旧模块设计的 Servlet API 集成时进行阻塞式写入或阻塞式读取。该缺陷导致响应式流内的相互作用模型退化,使其降级为普通的拉模型。

        WebFlux 通信模型取决于网络吞吐量以及可定义其自身控制流的底层传输协议。总而言之,Spring 5 引入了一个强大的工具,用于使用响应式流规范和 Project Reactor 构建响应式非阻塞应用程序。此外,Spring Boot 支持强大的依赖管理和自动配置,可以保护我们免受依赖地狱的侵害。

1.3、响应式 Spring Data

        Spring Data 主要提供对底层存储区域的同步阻塞访问。现在,Spring Data 框架提供了 ReactiveCrudRepository 接口,该接口暴露了 Project Reactor 的响应式类型。Spring Data 还提供了几个通过扩展 ReactiveCrudRepository 接口而与存储方法集成的模块。

  1. 基于 Spring Data Mongo 响应式模块的 MongoDB:与NoSQL 数据库之间的完全响应式非阻塞交互,同时也包含背压控制。
  2. 基于 Spring Data Cassandra 响应式模块的 Cassandra:与Cassandra 数据存储的异步非阻塞交互,支持基于TCP 流控制的背压。
  3. 基于 Spring Data Redis 响应式模块的 Redis:通过Lettuce Java 客户端实现的与 Redis 之间的响应式集成。
  4. 基于 Spring Data Couchbase 响应式模块的 Couchbase:通过基于 RxJava 的驱动程序实现的与 Couchbase 数据库之间的响应式Spring Data 集成。

        此外,Spring Boot 提供了额外的启动器模块,可以与所选的存储方法实现平滑集成。除了NoSQL 数据库,Spring Data 还引入了 Spring Data JDBC ,与 JDBC 轻量级集成,快速提供响应式 JDBC 连接。其他 Spring 框架模块的大多数改进以 WebFlux 的响应式能力或响应式 Spring Data 模块为基础。

1.4、响应式 Spring Session

        Spring 框架中与Spring Web 模块相关的另一个重要更新是 Spring Session 模块中的响应式支持。Spring Session 引入了 ReactiveSessionRepository,可以使用 Reactor 的 Mono 类型对存储的会话进行异步非阻塞访问。

        除此之外,作为响应式 Spring Data 的会话存储,Spring Session 还提供与 Redis 的响应式集成。可以通过包含以下依赖项来实现分布式 WebSession:

<dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

        为了实现响应式 Redis WebSession 管理,必须将这3 个依赖项组合在一个地方。同时,Spring Boot 负责提供 bean 的精确组合并生成合适的自动配置,以便顺利地运行 Web 应用程序。

1.5、响应式 Spring Security

        旧的Spring Security 使用 ThreadLocal 作为 SecurityContext 实例的存储方法。在单个Thread 内执行时,该技术很有效,在任何时候,都可以访问存储在ThreadLocal 中的SecurityContext。

        但是,在执行异步通信时,该技术就会出现问题。这时,必须提供额外的工作来将 ThreadLocal 内容传输到另一个Thread,并为Thread 实例之间的每个切换实例执行此操作。

        尽管Spring 框架通过使用一个额外的 ThreadLocal 扩展简化了 Threads 之间的 SecurityContext传输,但在基于 Project Reactor 或类似的响应式库应用响应式编程范例时,仍然会有问题。新一代 Spring Security 采用了 Reactor 上下文功能,以便在 Flux 或 Mono 流中传输安全上下文。通过这种方式,即使在运作着不同执行线程的复杂响应式流中,我们也可以安全地访问安全上下文。

1.6、响应式 Spring Cloud(重点🍕)

        首先,响应式影响了分布式系统的入口点,即网关(gateway)。很长一段时间,唯一能够将应用程序作为网关运行的 Spring 模块是 Spring Cloud Netflix Zuul 模块。Netflix Zuul 基于使用阻塞同步请求路由的 Servlet API。使处理请求获得更好性能的唯一方法是调整底层服务器线程池。这种模型的伸缩性无法与响应式方法相比。

        Spring Cloud 引入了新的 Spring Cloud Gateway 模块,该模块构建于 Spring WebFlux 之上,并在 Project Reactor 3 的支持下提供异步和非阻塞路由。除了新的网关模块,Spring Cloud Streams 还获得了Project Reactor 的支持,并且引入了更加细粒度的流模型。

        为了简化响应式系统的开发,Spring Cloud 引入了一个名为 Spring Cloud Function 的新模块,该模块旨在为构建我们自己的函数即服务(function as a service ,FaaS)解决方案提供必要的组件。如果没有适当的附加基础设施,Spring Cloud Function 模块将无法应用在普通开发中。SpringCloud Data Flow 不仅提供了这种可能性,还包含了Spring Cloud Function 的部分功能。

1.7、响应式 Spring Test

        Spring 生态系统提供了改进后的 Spring Test 和 Spring Boot Test 模块,它们扩展了一系列用于测试响应式 Spring 应用程序的附加功能。Spring Test 提供了一个 WebTestClient 来测试基于 WebFlux 的 Web 应用程序,同时,Spring Boot Test 使用普通的注解来处理测试套件的自动配置。

        同时,为了测试响应式流的 Publisher,Project Reactor 提供了Reactor-Test 模块,它与 Spring Test 和 Spring Boot Test 模块相结合,可以为使用响应式Spring 实现的业务逻辑编写完整的验证套件。

1.8、响应式监控

        基于 Project Reactor 和响应式 Spring 框架构建的面向生产的响应式系统应该暴露所有重要的运维指标。首先,Project Reactor 本身具有内置指标。它提供 Flux#metrics() 方法,可以跟踪响应式流中的不同事件。

        Spring 框架生态系统提供了更新后的 Spring Boot Actuator 模块,该模块支持应用程序监控和故障排除的主要指标。新一代SpringActuator 提供与 WebFlux 的完全集成,并使用其异步、非阻塞编程模型,以便有效地暴露指标端点。

        Spring Cloud Sleuth 模块提供了监控和跟踪应用程序的最终选项。该模块提供开箱即用的分布式跟踪,它的一个显著优点是支持 Project Reactor 的响应式编程,因此应用程序中的所有响应式工作流都可以被正确跟踪。

        Spring 生态系统不仅改进了内核框架的响应性,还负责面向生产的功能,而且支持详细的应用程序监控(这种监控甚至包括这些功能的响应式解决方案)。

2、WebFlux 的应用

2.1、基于微服务的系统

        WebFlux 的第一个应用是微服务系统。微服务系统最显著的特点是大量的I/O 通信。I/O 的存在,尤其是阻塞式I/O,会降低整体系统延迟和吞吐量。

2.1.1、微服务网关

1、Spring Cloud Gateway

        Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,Spring Cloud Gateway 旨在为微服务架构提供一种简单而有效的统一的 API 路由管理方式。Spring Cloud Gateway 作为 Spring Cloud 生态系中的网关,目标是替代 Netflix ZUUL,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。

2、功能特征
  1. 基于 Spring Framework 5 Project Reactor Spring Boot 2.0
  2. 动态路由
  3. Predicates 和 Filters 作用于特定路由
  4. 集成 Hystrix 断路器
  5. 集成 Spring Cloud DiscoveryClient
  6. 易于编写的 Predicates 和 Filters
  7. 限流
  8. 路径重写
3、工作流程

        客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到实际服务执行业务逻辑,然后返回。

        过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前( pre )或之后( post )执行业务逻辑。

2.2、大文件上传

<properties><java.version>11</java.version>
</properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>io.projectreactor</groupId><artifactId>reactor-test</artifactId><scope>test</scope></dependency>
</dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

src/main/java/com/lagou/webflux/demo/controller/FileController.java

import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.io.IOException;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;@RestController
public class FileController {@RequestMapping("/single")public Mono < String > singleFile(@RequestPart("file") Mono < FilePart > file) {return file.map(filepart -> {Path tmpFile = null;try {// 创建临时文件tmpFile = Files.createTempFile("file-",filepart.filename());} catch (IOException e) {e.printStackTrace();}System.out.println("文件路径:" + tmpFile.toAbsolutePath());// 异步文件channelAsynchronousFileChannel channel = null;try {// 打开指定文件写操作的channelchannel = AsynchronousFileChannel.open(tmpFile,StandardOpenOption.WRITE);} catch (IOException e) {e.printStackTrace();}DataBufferUtils.write(filepart.content(), channel, 0).doOnNext(System.out::println).doOnComplete(() -> {System.out.println("文件拷贝完成");}).subscribe();return tmpFile;}).map(tmp -> tmp.toFile()).flatMap(fileSingle -> file.map(FilePart::filename));}@RequestMapping(value = "/multi")public Mono < List < String >> multiFiles(@RequestPart("file") Flux < FilePart >filePartFlux) {return filePartFlux.map(filePart -> {Path tmpFile = null;try {tmpFile = Files.createTempFile("mfile-",filePart.filename());} catch (IOException e) {e.printStackTrace();}System.out.println(tmpFile.toAbsolutePath());// 对每个filePart执行写文件的方法filePart.transferTo(tmpFile.toFile());// 返回Path对象return tmpFile;}).map(tfile -> tfile.toFile()) // 将每个Path对象映射为文件.flatMap(fileSingle ->filePartFlux.map(FilePart::filename)).collectList();}
}
src/main/resources/static/index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>文件上传</title></head><body><form action="/single" method="post" enctype="multipart/form-data"><input type="file" name="file"><input type="submit" value="上传单个文件"></form><hr><form action="/multi" method="post" enctype="multipart/form-data"><input type="file" name="file"><input type="file" name="file"><input type="file" name="file"><input type="file" name="file"><input type="submit" value="上传多个文件"></form></body></html>

2.3、处理客户端连接速度慢的系统

        WebFlux 的第二个应用是构建系统,而这些系统的目标是在缓慢或不稳定网络连接条件下适用于移动设备客户端。要理解为什么WebFlux 在这个领域有用,就要回想一下在处理一个慢速连接时会发生什么。

        问题在于,将数据从客户端传输到服务器可能花费大量时间,并且相应的响应也可能花费大量时间。在使用单连接单线程模型的情况下,已连接客户端数量越多,系统崩溃的可能性越大。例如,黑客能很容易的通过使用拒绝服务(Denial-of-Service,DoS)攻击使我们的服务器不可用。

        相比之下,WebFlux 使我们能在不阻塞工作线程的情况下接受连接。这样,慢速连接不会导致任何问题。在等待传入请求体时,WebFlux 将继续接收其他连接而不会阻塞。响应式流抽象使我们能在需要时消费数据。这意味着服务器可以根据网络的就绪情况控制事件消费。

2.4、流系统或实时系统

        WebFlux 的另一个有用的应用是实时流系统。要了解WebFlux 为什么能在这一点上提供帮助,就要回想实时流系统是什么。

        首先,这些系统的特点是低延迟和高吞吐量。在流系统中,大多数数据是从服务器端传出的,因此客户端扮演消费者的角色。通常来自于客户端的事件少于来自于服务器端的事件。但是,在在线游戏等实时系统中,传入数据量等于传出数据量。

        使用非阻塞通信可以实现低延迟和高吞吐量。正如前文所述,非阻塞异步通信可以实现高效的资源利用,而基于Netty 或类似框架的系统可以实现最高的吞吐量和最低的延迟。然而,这种响应式框架有其自身的缺点,即使用通道和回调的复杂交互模型。

        尽管如此,响应式编程仍然可以巧妙地解决这两个问题。正如前面所说,响应式编程,尤其是响应式库(如Reactor 3)可以帮助我们构建一个异步的非阻塞流而只需要很少的开销。这些开销来自基础代码复杂性和可接受的学习曲线。这两种解决方案都包含在WebFlux中。使用Spring框架可以让我们轻松构建这样的系统。

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

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

相关文章

河道水位流量一体化自动监测系统:航运安全的护航使者

在广袤的水域世界中&#xff0c;航运安全始终是至关重要的课题。而河道水位流量一体化自动监测系统的出现&#xff0c;如同一位强大的护航使者&#xff0c;为航运事业的稳定发展提供了坚实的保障。 水位传感器&#xff1a;负责实时监测河道的水位变化。这些传感器通常采用先进的…

RHCE的学习(21)

第三章 Shell条件测试 用途 为了能够正确处理Shell程序运行过程中遇到的各种情况&#xff0c;Linux Shell提供了一组测试运算符。 通过这些运算符&#xff0c;Shell程序能够判断某种或者几个条件是否成立。 条件测试在各种流程控制语句&#xff0c;例如判断语句和循环语句中…

uni-app Vue3语法实现微信小程序样式穿透uview-plus框架

1 问题描述 我在用 uni-app vue3 语法开发微信小程序时&#xff0c;在项目中使用了 uview-plus 这一开源 UI 框架。在使用 up-text 组件时&#xff0c;想要给它添加一些样式&#xff0c;之前了解到微信小程序存在样式隔离的问题&#xff0c;也在uview-plus官网-注意事项中找到…

数据结构(双向链表——c语言实现)

双向链表相比于单向链表的优势&#xff1a; 1. 双向遍历的灵活性 双向链表&#xff1a;由于每个节点都包含指向前一个节点和下一个节点的指针&#xff0c;因此可以从头节点遍历到尾节点&#xff0c;也可以从尾节点遍历到头节点。这种双向遍历的灵活性使得在某些算法和操作中&a…

论文分享 | FuzzLLM:一种用于发现大语言模型中越狱漏洞的通用模糊测试框架

大语言模型是当前人工智能领域的前沿研究方向&#xff0c;在安全性方面大语言模型存在一些挑战和问题。分享一篇发表于2024年ICASSP会议的论文FuzzLLM&#xff0c;它设计了一种模糊测试框架&#xff0c;利用模型的能力去测试模型对越狱攻击的防护水平。 论文摘要 大语言模型中…

ES分词环境实战

文章目录 安装下载1.1 下载镜像1.2 单节点启动 防火墙设置异常处理【1】iptable链路中断 参考文档 参加完2024年11月软考&#xff0c;对ES的分词进行考查&#xff0c;前期有【 Docker 环境下安装部署 Elasticsearch 和 kibana】和【 Docker 环境下为 Elasticsearch 安装IK 分…

在 CentOS 系统上直接安装 MongoDB 4.0.25

文章目录 步骤 1&#xff1a;配置 MongoDB 官方源步骤 2&#xff1a;安装 MongoDB步骤 3&#xff1a;启动 MongoDB 服务步骤 4&#xff1a;验证安装步骤 5&#xff1a;可选配置注意事项 以下是在 CentOS 系统上直接安装 MongoDB 4.0.25 的详细步骤&#xff1a; 步骤 1&#x…

基于Vue+SpringBoot的求职招聘平台

平台概述 本平台是一个高效、便捷的人才与职位匹配系统&#xff0c;旨在为求职者与招聘者提供一站式服务。平台内设三大核心角色&#xff1a;求职者、招聘者以及超级管理员&#xff0c;每个角色拥有独特的功能模块&#xff0c;确保用户能够轻松完成从信息获取到最终录用的整个…

谈谈Spring的常见基础概念

文章是对Spring一些基础的底层概念进行分析&#xff0c;后续再遇到这些问题的时候&#xff0c;可以采用这些步骤进行详细解释。 一.谈谈SpringIOC的理解&#xff0c;原理与实现? 总&#xff1a; 1.控制反转&#xff1a; (1)原来的对象是由使用者来进行控制&#xff0c;有了S…

NAT网络地址转换——Easy IP

NAT网络地址转换 Tip&#xff1a; EasylP没有地址池的概念,使用接口地址作为NAT转换的公有地址。EasylP适用于不具备固定公网IP地址的场景:如通过DHCP, PPPOE拨号获取地址的私有网络出口,可以直接使用获取到的动态地址进行转换。 本次实验模拟nat协议配置 AR1配置如下&…

基于xr-frame实现微信小程序的手部、手势识别3D模型叠加和石头剪刀布游戏功能

前言 xr-frame是一套小程序官方提供的XR/3D应用解决方案&#xff0c;基于混合方案实现&#xff0c;性能逼近原生、效果好、易用、强扩展、渐进式、遵循小程序开发标准。xr-frame在基础库v2.32.0开始基本稳定&#xff0c;发布为正式版&#xff0c;但仍有一些功能还在开发&#…

【WRF-Urban】URBPARM_LCZ.TBL 查找表解释及内容

【WRF-Urban】URBPARM_LCZ.TBL 查找表解释及内容 URBPARM_LCZ.TBL 文件的作用URBPARM_LCZ.TBL 文件中的参数URBPARM_LCZ.TBL 的使用URBPARM_LCZ.TBL 文件内容如何调整或扩展 URBPARM_LCZ.TBL参考URBPARM_LCZ.TBL 文件是 WRF(天气研究与预报模型) 中用于处理 局地气候区(Loca…

nacos开启鉴权与配置加密

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、Nacos漏洞复现 1.1.查看配置 1.2.查看用户列表 1.3.注册新用户 二、Nacos开启鉴权 三、变更配置与信息加密 1.变更配置 2.信息加密 四、增强安全性 五、常见问…

AI Large Language Model

AI 的 Large Language model LLM , 大语言模型&#xff1a; 是AI的模型&#xff0c;专门设计用来处理自然语言相关任务。它们通过深度学习和庞大的训练数据集&#xff0c;在理解和生成自然语言文本方面表现出色。常见的 LLM 包括 OpenAI 的 GPT 系列、Google 的 PaLM 和 Meta…

前端三剑客(二):CSS

目录 1. CSS 基础 1.1 什么是 CSS 1.2 语法格式 1.3 引入方式 1.3.1 行内样式 1.3.2 内部样式 1.3.3 外部样式 1.4 CSS 编码规范 2. 选择器 2.1 标签选择器 2.2 id 选择器 2.3 class 选择器(类选择器) 2.4 复合选择器 2.5 通配符选择器 3. 常用 CSS 样式 3.1 c…

华为Ensp模拟器配置OSPF路由协议

目录 简介 实验步骤 Pc配置 路由器配置 OSPF配置 交换机配置 简介 开放式最短路径优先 (OSPF) 协议深度解析 简介 开放式最短路径优先&#xff08;Open Shortest Path First, OSPF&#xff09;是一种内部网关协议&#xff08;IGP&#xff09;&#xff0c;用于在自治系统…

【C++】绘制内存管理的地图

生活是属于每个人自己的感受&#xff0c;不属于任何人的看法。 前言 这是我自己学习C的第二篇博客总结。后期我会继续把C学习笔记开源至博客上。 上一期笔记是关于C的类与对象础知识&#xff0c;没看的同学可以过去看看&#xff1a; 【C】面向对象编程的艺术之旅-CSDN博客https…

基于YOLOv8深度学习的医学影像骨折检测诊断系统研究与实现(PyQt5界面+数据集+训练代码)

本论文深入研究并实现了一种基于YOLOV8深度学习模型的医学影像骨折检测与诊断系统&#xff0c;旨在为医学影像中的骨折检测提供高效且准确的自动化解决方案。随着医疗影像技术的快速发展&#xff0c;临床医生需要从大量复杂的医学图像中精确、快速地识别病灶区域&#xff0c;特…

【vulhub】nginx解析漏洞(nginx_parsing_vulnerability)

1. nginx解析漏洞原理 fastcgi 在处理’.php’文件时发现文件并不存在,这时 php.ini 配置文件中cgi.fix_pathinfo1 发挥作用,这项配置用于修复路径,如果当前路径不存在则采用上层路径 (1)由于 nginx.conf的配置导致 nginx把以’.php”结尾的文件交给 fastcgi 处理,为此可以构造…

如何通过统一权限管理打破异构系统的安全屏障

企业在运营过程中面临着众多异构系统的整合挑战&#xff0c;这些异构系统由于其不同的技术架构、数据格式和安全机制等&#xff0c;给信息管理带来了诸多挑战。其中&#xff0c;“信息孤岛”问题尤为突出&#xff0c;而异构环境下的统一授权管理系统则成为解决这一问题的关键。…