Spring Boot 3.2.0 Tomcat虚拟线程初体验 (部分装配解析)

写在前面

  • spring boot 3 已经提供了对虚拟线程的支持。

  • 虚拟线程和平台线程主要区别在于,虚拟线程在运行周期内不依赖操作系统线程:它们与硬件脱钩,因此被称为 “虚拟”。这种解耦是由 JVM 提供的抽象层赋予的。

  • 虚拟线程的运行成本远低于平台线程。消耗的内存要少得多。这就是为什么可以创建数百万个虚拟线程而不会出现内存不足的问题,而标准平台(或内核)线程只能创建数百个。

  • 虚拟线程会优先使用JVM提供,如果不能使用JVM提供,则考虑使用由平台线程支持的“虚拟线程” ,相关源代码参考java.lang.ThreadBuilders#newVirtualThread

版本要求

  • spring boot 3.2.0
  • jdk 21

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>net.jlxxw</groupId><artifactId>boot3-demo</artifactId><version>1.0.0.20231128</version><name>boot3-demo</name><description>boot3-demo</description><properties><java.version>21</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>3.2.0</spring-boot.version></properties><dependencies><dependency><groupId>org.apache.httpcomponents.client5</groupId><artifactId>httpclient5-fluent</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><configuration><!-- imageName用于设置生成的二进制文件名称 --><imageName>${project.artifactId}</imageName><!-- mainClass用于指定main方法类路径 --><!--                                <buildArgs>--><!--                                    no-fallback--><!--                                </buildArgs>--></configuration>
<!--                <executions>-->
<!--                    <execution>-->
<!--                        <id>build-native</id>-->
<!--                        <goals>-->
<!--                            <goal>compile-no-fork</goal>-->
<!--                        </goals>-->
<!--                        <phase>package</phase>-->
<!--                    </execution>-->
<!--                </executions>--></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

yml

spring:#启动虚拟线程的必须配置threads:virtual:# 启用虚拟线程技术,增加系统并发能力enabled: true

自动装配解析

Tomcat 虚拟线程自动配置类

org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration.TomcatWebServerFactoryCustomizerConfiguration#tomcatVirtualThreadsProtocolHandlerCustomizer

/** Copyright 2012-2023 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.springframework.boot.autoconfigure.web.embedded;import io.undertow.Undertow;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.UpgradeProtocol;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.Loader;
import org.xnio.SslClientAuthMode;
import reactor.netty.http.server.HttpServer;import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment;
import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.thread.Threading;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;/*** {@link EnableAutoConfiguration Auto-configuration} for embedded servlet and reactive* web servers customizations.** @author Phillip Webb* @since 2.0.0*/
@AutoConfiguration
@ConditionalOnNotWarDeployment
@ConditionalOnWebApplication
@EnableConfigurationProperties(ServerProperties.class)
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {/*** Nested configuration if Tomcat is being used.*/@Configuration(proxyBeanMethods = false)@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })public static class TomcatWebServerFactoryCustomizerConfiguration {@Beanpublic TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment,ServerProperties serverProperties) {return new TomcatWebServerFactoryCustomizer(environment, serverProperties);}@Bean@ConditionalOnThreading(Threading.VIRTUAL)TomcatVirtualThreadsWebServerFactoryCustomizer tomcatVirtualThreadsProtocolHandlerCustomizer() {return new TomcatVirtualThreadsWebServerFactoryCustomizer();}}/*** Nested configuration if Jetty is being used.*/@Configuration(proxyBeanMethods = false)@ConditionalOnClass({ Server.class, Loader.class, WebAppContext.class })public static class JettyWebServerFactoryCustomizerConfiguration {@Beanpublic JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment,ServerProperties serverProperties) {return new JettyWebServerFactoryCustomizer(environment, serverProperties);}@Bean@ConditionalOnThreading(Threading.VIRTUAL)JettyVirtualThreadsWebServerFactoryCustomizer jettyVirtualThreadsWebServerFactoryCustomizer(ServerProperties serverProperties) {return new JettyVirtualThreadsWebServerFactoryCustomizer(serverProperties);}}/*** Nested configuration if Undertow is being used.*/@Configuration(proxyBeanMethods = false)@ConditionalOnClass({ Undertow.class, SslClientAuthMode.class })public static class UndertowWebServerFactoryCustomizerConfiguration {@Beanpublic UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(Environment environment,ServerProperties serverProperties) {return new UndertowWebServerFactoryCustomizer(environment, serverProperties);}}/*** Nested configuration if Netty is being used.*/@Configuration(proxyBeanMethods = false)@ConditionalOnClass(HttpServer.class)public static class NettyWebServerFactoryCustomizerConfiguration {@Beanpublic NettyWebServerFactoryCustomizer nettyWebServerFactoryCustomizer(Environment environment,ServerProperties serverProperties) {return new NettyWebServerFactoryCustomizer(environment, serverProperties);}}}

在这里插入图片描述

Tomcat虚拟线程定制器

org.springframework.boot.autoconfigure.web.embedded.TomcatVirtualThreadsWebServerFactoryCustomizer

/** Copyright 2012-2023 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.springframework.boot.autoconfigure.web.embedded;import org.apache.coyote.ProtocolHandler;
import org.apache.tomcat.util.threads.VirtualThreadExecutor;import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.core.Ordered;/*** Activates {@link VirtualThreadExecutor} on {@link ProtocolHandler Tomcat's protocol* handler}.** @author Moritz Halbritter* @since 3.2.0*/
public class TomcatVirtualThreadsWebServerFactoryCustomizerimplements WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory>, Ordered {@Overridepublic void customize(ConfigurableTomcatWebServerFactory factory) {factory.addProtocolHandlerCustomizers((protocolHandler) -> protocolHandler.setExecutor(new VirtualThreadExecutor("tomcat-handler-")));}@Overridepublic int getOrder() {return TomcatWebServerFactoryCustomizer.ORDER + 1;}}

新的虚拟线程池

org.apache.tomcat.util.threads.VirtualThreadExecutor

/**  Licensed to the Apache Software Foundation (ASF) under one or more*  contributor license agreements.  See the NOTICE file distributed with*  this work for additional information regarding copyright ownership.*  The ASF licenses this file to You under the Apache License, Version 2.0*  (the "License"); you may not use this file except in compliance with*  the License.  You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0**  Unless required by applicable law or agreed to in writing, software*  distributed under the License is distributed on an "AS IS" BASIS,*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*  See the License for the specific language governing permissions and*  limitations under the License.*/
package org.apache.tomcat.util.threads;import java.util.concurrent.Executor;import org.apache.tomcat.util.compat.JreCompat;/*** An executor that uses a new virtual thread for each task.*/
public class VirtualThreadExecutor implements Executor {private final JreCompat jreCompat = JreCompat.getInstance();private Object threadBuilder;public VirtualThreadExecutor(String namePrefix) {threadBuilder = jreCompat.createVirtualThreadBuilder(namePrefix);}@Overridepublic void execute(Runnable command) {jreCompat.threadBuilderStart(threadBuilder, command);}
}

测试对比效果

启用虚拟线程

在这里插入图片描述

未启用虚拟线程

在这里插入图片描述

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

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

相关文章

ELK---filebeat日志收集工具

elk---filebeat日志收集工具 filebeat是一个轻量级的日志收集工具&#xff0c;所使用的资源比logstash部署和启动时使用的资源小的多。 filebeat可以在非Java环境收集日志&#xff0c;它可以代替logstash在非Java环境上收集日志。 filebeat无法实现数据的过滤&#xff0c;一般…

fiddler测试弱网别再去深山老林测了,这样做就能达到弱网效果了!

弱网测试 概念&#xff1a;弱网看字面意思就是网络比较弱&#xff0c;我们通称为信号差&#xff0c;网速慢。 意义&#xff1a;模拟在地铁、隧道、电梯和车库等场景下使用APP &#xff0c;网络会出现延时、中断和超时等情况。 添加图片注释&#xff0c;不超过 140 字&#xf…

【API 自动化测试】Eolink Apikit 图形用例详解

Eolink Apikit 的图形用例是指通过图形化的方式去表现 API 流程测试。它包括了条件选择器、单个 API 步骤和操作集等组件。 相较于前面推荐的表格化的通用用例&#xff0c;图形用例可以让测试人员更方便地设计和管理 API 流程测试&#xff0c;同时也更加的灵活。 添加图形用例…

大疆开发板A型基于HAL库驱动M3508直流无刷电机及PID控制

1.首先&#xff0c;我们先了解一下大疆开发板A型的资料&#xff0c;官方有提供 官网&#xff1a;RoboMaster 机甲大师赛 芯片型号STM32F427IIH6 2.了解M3508直流无刷电机的资料&#xff0c;官网有提供 3.于是我找到了C620电调的资料&#xff0c;官网有提供 4.好了&#xff0…

Python小技巧:探索函数调用为何加速代码执行

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python 作为一种解释型语言&#xff0c;其执行速度相对于编译型语言可能会较慢。然而&#xff0c;在Python中&#xff0c;通常观察到代码在函数中运行得更快的现象。这个现象主要是由于函数调用的内部优化和解释…

ASCII值对照表

ASCII码是一种7位编码&#xff0c;但它存放时必须占全1个字节&#xff0c;也即占用8位&#xff0c;最高位为0&#xff0c;其余7位表示ASCII码。 ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符包括所有的大写和小写字母&#xff0c;数字0 到9、标点符…

平凯星辰 TiDB 获评 “2023 中国金融科技守正创新扬帆计划” 十佳优秀实践奖

11 月 10 日&#xff0c;2023 金融街论坛年会同期举办了“第五届成方金融科技论坛——金融科技守正创新论坛”&#xff0c;北京金融产业联盟发布了“扬帆计划——分布式数据库金融应用研究与实践优秀成果”&#xff0c; 平凯星辰提报的实践报告——“国产 HTAP 数据库在金融规模…

【Android Jetpack】Hilt 依赖注入框架

文章目录 依赖注入DaggerHiltKoin添加依赖项Hilt常用注解的含义HiltAndroidAppAndroidEntryPointInjectModuleInstallInProvidesEntryPoint Hilt组件生命周期和作用域如何使用 Hilt 进行依赖注入 依赖注入 依赖注入是一种软件设计模式&#xff0c;它允许客户端从外部源获取其依…

多线程(进程池代码)

线程池介绍 那究竟什么是线程池呢&#xff1f; 线程池是一种线程使用模式. 线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能. 而线程池维护着多个线程&#xff0c;等待着监督管理者分配可并发执行的任务. 这避免了在处理短时间任务时创建与销毁线程的代价. 线…

springcloud nacos配置优先级研究及配置管理最佳实践

目录 背景工具版本SpringCloud配置存放位置及相应优先级代码中nacosjar包外挂 多种配置共同存在时的优先级项目配置管理最佳实践无nacos的情况有nacos的情况 参考文献 背景 公司有很多应用是基于SpringBoot/SpringCloud开发。由于在配置文件中经常会涉及数据库账号密码之类的敏…

局部内部类(内部类) - Java

局部内部类 说明&#xff1a;局部内部类是定义在外部类的局部位置&#xff0c;比如方法中&#xff0c;并且有类名。 LocalInnerClass.java 非常重要的几点&#xff01;&#xff01; 局部内部类本质还是一个类&#xff0c;该有的属性方法也都可以有。【举例a.见下文】可以直接…

【Python 零基础入门】Numpy 常用函数 通用函数 保存加载

【Python 零基础入门】内容补充 4 Numpy 常用函数 通用函数 & 保存加载 概述通用函数np.sqrt 平方根np.log 对数np.exp 指数np.sin 正弦 点积和叉积np.dot 点积叉积 矩阵乘法np.matmul 保存 & 加载np.save 保存单个数组np.savez 保存多个数组np.savez_compressed 保存n…