【spring 】支持spring WebFlux 的容器

2024-06-13 06:52

本文主要是介绍【spring 】支持spring WebFlux 的容器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

spring WebFlux 是 Spring 5 引入的响应式 Web 框架,它支持非阻塞、事件驱动的编程模型,特别适合处理高并发的场景。

Spring WebFlux 可以运行在多种容器上

包括下面:

  1. Netty:

    • Netty 是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。Spring WebFlux 默认使用 Netty 作为其服务器容器。

  2. Undertow:

    • Undertow 是一个用 Java 编写的灵活的高性能 Web 服务器,它提供了基于 NIO 的非阻塞 HTTP 和 WebSocket 支持。Spring Boot 支持将 Undertow 作为其嵌入式服务器之一。

  3. Tomcat:

    • Tomcat 是一个广泛使用的 Servlet 容器,支持传统的 Servlet 和 JSP 技术。从 Spring Boot 2.0 开始,Tomcat 也支持非阻塞 I/O,因此可以与 Spring WebFlux 一起使用。

  4. Jetty:

    • Jetty 是一个灵活的、轻量级的 Web 服务器和 Servlet 引擎,它也支持非阻塞 I/O。Spring Boot 同样支持将 Jetty 作为其嵌入式服务器之一。

在选择容器时,需要考虑应用程序的需求和容器的特性。例如,如果你的应用程序需要处理大量的并发连接,那么 Netty 或 Undertow 可能是更好的选择,因为它们在设计上就是非阻塞的,可以更有效地利用系统资源。而 Tomcat 和 Jetty 虽然也支持非阻塞 I/O,但它们最初是为阻塞 I/O 设计的,因此在某些场景下可能不如 Netty 和 Undertow 高效。

使用Netty 容器

要在 Spring WebFlux 中使用 Netty 容器,你不需要显式地配置任何依赖,因为 Spring Boot 的 spring-boot-starter-webflux 启动器已经包含了所需的 Netty 依赖。当你创建一个新的 Spring WebFlux 项目时,只需添加 spring-boot-starter-webflux 依赖,Spring Boot 会自动配置并使用 Netty 作为服务器容器。

添加依赖:

Maven 示例 (pom.xml):

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency>
</dependencies>
编写配置类
mport org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class NettyConfig {@Beanpublic WebServerFactoryCustomizer<NettyReactiveWebServerFactory> customizer() {return factory -> {// 自定义Netty参数factory.addServerCustomizers(builder ->builder// 设置工作线程池大小.workerEventLoopGroup(NettyThreadFactory.create("netty-worker", 4)) // 设置监听线程池大小.bossEventLoopGroup(NettyThreadFactory.create("netty-boss", 1)) );};}
}
编写响应式控制器:


创建一个响应式控制器来处理 HTTP 请求。Spring WebFlux 使用 @RestController 和 @RequestMapping 等注解,但也可以使用函数式端点。

示例控制器 (@RestController):
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;@RestController
public class DemoController {@GetMapping("/demo")public Mono<String> demo() {return Mono.just(" I am a  Demo!");}
}
 
函数式端点 (RouterFunction):
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;@Configuration
public class DemoRouter {@Beanpublic RouterFunction<ServerResponse> routeHello(DemoHandler demoHandler) {return route(GET("/demo"), demoHandler::demo);}
}
处理程序类
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;@Component
public class DemoHandler {public Mono<ServerResponse> demo(ServerRequest request) {return ServerResponse.ok().body(Mono.just("I am a Demo!"), String.class);}
}

运行这个应用程序时,Spring Boot 将自动使用 Netty 作为服务器容器,并在默认端口(通常是 8080)上启动服务。你可以通过访问 http://localhost:8080/demo来测试你的响应式控制器。

使用Undertow容器

Undertown 的优势如下:

  1. 支持 HTTP/2:Undertow 开箱即支持 HTTP/2,无需重写启动类路径。
  2. 支持 HTTP Upgrade:允许通过 HTTP 端口复用多种协议。
  3. 支持 Web Socket:Undertow 提供对 Web Sockets 的全面支持,包括 JSR-356 支持。
  4. Servlet 4.0:Undertow 支持 Servlet 4.0,包括对嵌入式 Servlet 的支持。还可以在同一部署中混合使用 Servlet 和原生 undertow 非阻塞 handler。
  5. 可嵌入式:只需几行代码,即可将 Undertow 嵌入应用程序或独立运行。
  6. 灵活性:Undertow 通过链式 handler 进行配置,可以根据需求灵活地添加功能。

要在 Spring Boot 应用程序中使用 Undertow 作为服务器容器,你需要在项目的依赖中指定 spring-boot-starter-web 而不是 spring-boot-starter-webflux,因为 Undertow 支持传统的 Servlet 3.1 非阻塞 I/O,同时也支持 Spring MVC。

添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
配置Undertow

你可以在application.propertiesapplication.yml中配置Undertow的相关参数,例如端口、线程池大小等。

application.yml示例:
server:port: 8080undertow:buffer-size: 1024worker-threads: 8direct-buffers: true
application.properties示例:
server.port=8080
server.undertow.buffer-size=1024
server.undertow.direct-buffers=true
server.undertow.worker-threads: 8
编写反应式控制器
mport org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;@RestController
public class DemoController {@GetMapping("/demo")public Flux<String> demo() {return Flux.just("demo", "from", "Spring", "WebFlux", "with", "Undertow");}
}

运行这个应用程序时,Spring Boot 将自动使用 Undertow 作为服务器容器,并在配置的端口(默认是 8080)上启动服务。你可以通过访问 http://localhost:8080/demo来测试控制器。

【注意】如果你想要使用 Undertow 的非阻塞特性,你需要确保你的应用程序代码也支持非阻塞 I/O,例如使用 Spring WebFlux 或 Servlet 3.1 的异步支持。如果你使用的是传统的 Spring MVC,那么 Undertow 的非阻塞特性可能不会被充分利用。

UndertowServletWebServerFactory 配置类的细节:官方文档

Undertow配置属性

配置项说明示例
server.undertow.accesslog.dirUndertow 访问日志目录。
server.undertow.accesslog.enabled是否启用访问日志。FALSE
server.undertow.accesslog.pattern访问日志的格式。common
server.undertow.accesslog.prefix日志文件前缀。access_log.
server.undertow.accesslog.rotate是否开启日志滚动。TRUE
server.undertow.accesslog.suffix日志文件后缀。log
server.undertow.always-set-keep-alive是否应在所有响应中添加 Connection: keep-alive Header,即使 HTTP 规范没有要求。TRUE
server.undertow.buffer-size每个 buffer 的大小。默认大小是根据 JVM 可用的最大内存确定的。
server.undertow.decode-slash是否应解码已编码的斜线字符(%2F)。如果前端代理不执行相同的解码,解码可能会导致安全问题。只有在传统应用程序需要时才启用。设置后,server.undertow.allow-encoded-slash 无效。
server.undertow.decode-url是否对 URL 进行解码。禁用时,URL 中的百分比编码字符将保持原样。TRUE
server.undertow.direct-buffers是否在 Java 堆外分配 buffer。默认大小是根据 JVM 可用的最大内存确定的。
server.undertow.eager-filter-init是否应在启动时初始化 servlet FilterTRUE
server.undertow.max-cookies允许的最大 cookie 数量。这一限制是为了防止基于哈希碰撞的 DOS 攻击。200
server.undertow.max-headers允许的最大 header 数量。这一限制是为了防止基于哈希碰撞的 DOS 攻击。
server.undertow.max-http-post-sizeHTTP post content 的最大大小。当值为-1(默认值)时,大小为无限。-1B
server.undertow.max-parameters允许查询或路径参数的最大数量。这一限制是为了防止基于哈希碰撞的 DOS 攻击。
server.undertow.no-request-timeout在服务器关闭连接之前,连接在不处理请求的情况下闲置的时间。
server.undertow.options.server.*在 io.undertow.UndertowOptions 中定义的服务器选项。
server.undertow.options.socket.*在 org.xnio.Options 中定义的 socket 选项。
server.undertow.preserve-path-on-forward转发请求时是否保留请求路径。FALSE
server.undertow.threads.ioI/O 线程数。默认值为可用的处理器数量。
server.undertow.threads.workerWorker 线程数。默认为 I/O 线程数的 8 倍。
server.undertow.url-charset用于解码 URL 的字符集。UTF-8




这篇关于【spring 】支持spring WebFlux 的容器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1056579

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2