【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中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

Java中的.close()举例详解

《Java中的.close()举例详解》.close()方法只适用于通过window.open()打开的弹出窗口,对于浏览器的主窗口,如果没有得到用户允许是不能关闭的,:本文主要介绍Java中的.... 目录当你遇到以下三种情况时,一定要记得使用 .close():用法作用举例如何判断代码中的 input

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S