来源:medium.com/@egorponomarev
Spring Boot 3.2 前几日发布,让我们用 Java 21、GraalVM 和虚拟线程来尝试一下。
Spring Boot 3.2 支持:
Java 21
虚拟线程
原生镜像(自 2022 年 11 月 Spring Boot 3.0 发布以来,Spring Boot 已在生产环境中支持 GraalVM 原生镜像)
Java 21
我们期待 2023 年 9 月 19 日发布的 Java 21,Spring Boot 3.2 已经做到完全支持了。
正如所声明的那样,Java 21 提供了数千项性能、稳定性和安全性改进,包括平台增强功能,可帮助开发人员提高生产力并推动整个组织的创新和增长。
虚拟线程
更重要的更新之一是虚拟线程,这是 Project Loom 提供的功能。我们不打算深入细节,官方 JEP 提供了很好的解释:
GraalVM 和本机镜像
GraalVM 是一种高性能 JDK,可以使用替代的即时 (JIT) 编译器来加快 Java 和基于 JVM 的应用程序的性能。
Native Image 是一种提前将 Java 代码编译为独立可执行文件(称为本机映像)的技术。该可执行文件包括应用程序类、其依赖项中的类、运行时库类以及来自 JDK 的静态链接本机代码。
它不在 Java VM 上运行,但包含来自不同运行时系统的必要组件,如内存管理、线程调度等。与 JVM 相比,生成的程序具有更快的启动时间和更低的运行时内存开销。
尝鲜一下
让我们从安装 Java 21.0.1 graal 开始,最简单的方法是使用SDKMAN 并将其指定为您机器的默认 Java 版本:
sdk install java 21.0.1-graal
sdk default java 21.0.1-graal
另一种安装方法是手动下载
我们将使用Spring Initializr页面创建一个新的Spring Boot项目,使用 Spring Boot 3.2.0、Java 21、Gradle-Groovy以及Spring Web和GraalVM本地支持依赖项。
要在 Spring Boot 3.2 中启用虚拟线程,我们只需在 application.yml 或 application.properties 文件中设置一个属性:
spring.threads.virtual.enabled:true
这个配置起到的作用:
Tomcat 将使用虚拟线程来处理 HTTP 请求。这意味着处理 Web 请求的应用程序代码(例如控制器中的方法)将在虚拟线程上运行。
调用@Async方法时,Spring MVC 的异步请求处理和 Spring WebFlux 的阻塞执行支持现在将利用虚拟线程
标记有@Scheduled的方法将在虚拟线程上运行
因此,我们将尝试使用这 3 个集成来实现虚拟线程。
此外,一些特定的集成将在虚拟线程上工作,例如 RabbitMQ/Kafka 监听器,以及 Spring Data Redis/Apache pulsar 相关的集成。但这些集成超出了本文的范围,有兴趣的可以参考 Spring Boot 3.2 官方示例。
代码
1.对于 Tomcat 传入的 HTTP 请求,我们创建一个简单的控制器:
@RestController @RequestMapping("/test") publicclassTestController{ privatestaticfinalLoggerlog=LoggerFactory.getLogger(TestController.class); @GetMapping publicvoidtest(){ log.info("Restcontrollermethodhasbeencalled{}",Thread.currentThread()); } }
2.异步任务
我们将在应用程序启动时调用其“run”方法
@Component publicclassAsyncTaskExecutorService{ privatestaticfinalLoggerlog=LoggerFactory.getLogger(AsyncTaskExecutorService.class); @Async publicvoidrun(){ log.info("Asynctaskmethodhasbeencalled{}",Thread.currentThread()); } }
3.Scheduled 定时任务
一个简单的方法,每 15 秒调用一次
@Component publicclassSchedulerService{ privatestaticfinalLoggerlog=LoggerFactory.getLogger(SchedulerService.class); @Scheduled(fixedDelayString="15000") publicvoidrun(){ log.info("Scheduledmethodhasbeencalled{}",Thread.currentThread()); } }
让我们运行我们的应用程序:
./gradlewbootRun
并调用我们的端点
curl—位置—请求GET'localhost:8085/test'
我们得到什么:
StartingAppApplicationusingJava21.0.1withPID38126 StartedAppApplicationin1.131seconds(processrunningfor1.491) AsynctaskmethodhasbeencalledVirtualThread[#52,task-1]/runnable@ForkJoinPool-1-worker-5 ScheduledmethodhasbeencalledVirtualThread[#46,scheduling-1]/runnable@ForkJoinPool-1-worker-1 RestcontrollermethodhasbeencalledVirtualThread[#62,tomcat-handler-0]/runnable@ForkJoinPool-1-worker-1 ScheduledmethodhasbeencalledVirtualThread[#46,scheduling-1]/runnable@ForkJoinPool-1-worker-1
我们可以看到我们的方法的日志链接到公共 ForkJoinPool 线程池。
根据JEP:预期行为:
JDK 的虚拟线程调度程序是一个工作窃取的 ForkJoinPool,它以 FIFO 模式运行。调度程序的并行度是可用于调度虚拟线程的平台线程的数量。
现在让我们在 GraalVM 上运行它。
首先,我们需要构建一个 GraalVM 本机映像:(此命令可能需要几分钟)然后运行:(使用您的应用程序的名称而不是“app”)
./gradlewnativeCompile ./build/native/nativeComplie/app
它也可以工作,并且启动时间要快得多,这符合声明的“与 JVM 相比,生成的程序具有更快的启动时间和更低的运行时内存开销”。
在这里您可以找到包含本文中使用的代码的存储库来源
结论
Spring Boot 3.2 是我们一直在等待的东西!具有虚拟线程的本机映像允许我们编写能够提供与 Go 类似级别的性能和可扩展性的代码,从而保持 JVM 的强大生态系统。
但是,您必须考虑到并非所有库都已采用其代码来与虚拟线程正常工作(在大多数情况下,它正在用 ReentrantLock 替换“synchronize”块),您应该小心虚拟线程将使用的逻辑。
审核编辑:汤梓红
-
JAVA
+关注
关注
19文章
2980浏览量
105584 -
线程
+关注
关注
0文章
507浏览量
19839 -
镜像
+关注
关注
0文章
173浏览量
10861 -
SpringBoot
+关注
关注
0文章
175浏览量
214
原文标题:Spring Boot 3.2 正式发布,开箱即用的虚拟线程和 GraalVM,尝鲜一下!
文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
Spring Boot如何实现异步任务
Spring Boot虚拟线程和Webflux性能对比

使用Spring Boot 3.2虚拟线程搭建静态文件服务器

请问6455支持对16位flash操作吗?
Spring Boot从零入门1 详述
Spring Boot特有的实践
强大的Spring Boot 3.0要来了
用这4招 优雅的实现Spring Boot异步线程间数据传递
Spring Boot Actuator快速入门
Spring Boot启动 Eureka流程

Spring Boot的启动原理

评论