👉 这是一个或许对你有用的社群
🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入芋道快速开发平台知识星球。下面是星球提供的部分资料:
👉这是一个或许对你有用的开源项目
国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。
功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:
  • Boot 地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 地址:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn

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 提供了数千项性能、稳定性和安全性改进,包括平台增强功能,可帮助开发人员提高生产力并推动整个组织的创新和增长。
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

虚拟线程

更重要的更新之一是虚拟线程,这是 Project Loom 提供的功能。我们不打算深入细节,官方 JEP 提供了很好的解释:
https://openjdk.org/jeps/444
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

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
另一种安装方法是手动下载
https://www.graalvm.org/downloads/
我们将使用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
{

privatestaticfinal
 Logger log = LoggerFactory.getLogger(TestController
.class)
;


@GetMapping
publicvoidtest()
{

        log.info(
"Rest controller method has been called {}"
, Thread.currentThread());

    }

}

2.异步任务
我们将在应用程序启动时调用其“run”方法
@Component
publicclassAsyncTaskExecutorService
{

privatestaticfinal
 Logger log = LoggerFactory.getLogger(AsyncTaskExecutorService
.class)
;


@Async
publicvoidrun()
{

        log.info(
"Async task method has been called {}"
, Thread.currentThread());

    }

}

3.Scheduled 定时任务
一个简单的方法,每 15 秒调用一次
@Component
publicclassSchedulerService
{

privatestaticfinal
 Logger log = LoggerFactory.getLogger(SchedulerService
.class)
;


@Scheduled
(fixedDelayString = 
"15000"
)

publicvoidrun()
{

        log.info(
"Scheduled method has been called {}"
, Thread.currentThread());

    }

}

让我们运行我们的应用程序:
./gradlew bootRun

并调用我们的端点
curl — 位置 — 请求 GET 
'localhost:8085/test'
我们得到什么:
Starting AppApplication using Java 
21.0.1
 with PID 
38126
Started AppApplication in 
1.131
 seconds (process running 
for1.491
)

Async task method has been called VirtualThread[#
52
,task-
1
]/runnable
@ForkJoinPool
-
1
-worker-
5
Scheduled method has been called VirtualThread[#
46
,scheduling-
1
]/runnable
@ForkJoinPool
-
1
-worker-
1
Rest controller method has been called VirtualThread[#
62
,tomcat-handler-
0
]/runnable
@ForkJoinPool
-
1
-worker-
1
Scheduled method has been called VirtualThread[#
46
,scheduling-
1
]/runnable
@ForkJoinPool
-
1
-worker-
1
我们可以看到我们的方法的日志链接到公共 ForkJoinPool 线程池。
根据JEP:预期行为:
JDK 的虚拟线程调度程序是一个工作窃取的 ForkJoinPool,它以 FIFO 模式运行。调度程序的并行度是可用于调度虚拟线程的平台线程的数量。
现在让我们在 GraalVM 上运行它。
首先,我们需要构建一个 GraalVM 本机映像:(此命令可能需要几分钟)然后运行:(使用您的应用程序的名称而不是“app”)
./gradlew nativeCompile


./build/
native
/nativeComplie/app

它也可以工作,并且启动时间要快得多,这符合声明的“与 JVM 相比,生成的程序具有更快的启动时间和更低的运行时内存开销”。
在这里您可以找到包含本文中使用的代码的存储库来源:
https://github.com/egor-ponomarev/spring-boot3.2-with-graalvm-virtual-threads-example

结论

Spring Boot 3.2 是我们一直在等待的东西!具有虚拟线程的本机映像允许我们编写能够提供与 Go 类似级别的性能和可扩展性的代码,从而保持 JVM 的强大生态系统。
但是,您必须考虑到并非所有库都已采用其代码来与虚拟线程正常工作(在大多数情况下,它正在用 ReentrantLock 替换“synchronize”块),您应该小心虚拟线程将使用的逻辑。

欢迎加入我的知识星球,全面提升技术能力。
👉 加入方式,长按”或“扫描”下方二维码噢
星球的内容包括:项目实战、面试招聘、源码解析、学习路线。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
继续阅读
阅读原文