Helidon 4用Java虚拟线程重写


本文阐述了“支持虚拟线程”和“基于虚拟线程”的主要区别!

在 Loom 项目宣布并发布后,许多微服务框架声明支持虚拟线程。Helidon 4 实际上是基于虚拟线程,而不是仅仅支持虚拟线程:

  • “基于”是将虚拟线程作为核心
  • “支持”是其他技术作为核心,只是在外围支持虚拟线程,表面上可供选项高

那么,支持虚拟线程和基于虚拟线程有什么区别呢?

Java 中的线程只是操作系统线程的包装器。这一事实使它们成为相当昂贵的资源。你不能对它们做得太多。启动一个线程并在它们之间切换需要花费大量时间。因此,我们在不同的线程池执行器中复用线程。

微服务的典型任务的本质是它们有很多,它们并行运行,而且运行时间很短,因此它们不会阻塞线程。通常,请求数多于可用线程数。每个线程运行每个请求的模式并不是最佳的,因此行业转向反应式范例和异步处理。

大多数框架都依赖 Netty,它异步管理连接以通过它们发送数据,从而提供良好的性能。开发人员通常应该创建异步代码以提高性能。而且编写、调试和维护都很困难。

支持虚拟线程
当 Project Loom 出现时,许多微服务框架开始尝试它(暗指SpringBoot等框架):

  • 将常规线程池执行器更改为虚拟线程池执行器。
  • 或者创建一个混合模式,根据某些标记(例如注释)将某些任务卸载到虚拟线程中。

由于执行器中有更多可用的(虚拟)线程,因此这种方法在一定程度上提高了性能。但是,在任务管理中却消耗了老的所有反应/异步开销。

在 Helidon 中,我们也尝试过这种方法。在 Helidon 2 和 3 的早期版本中,就有在 Netty 上启用 Loom 线程池执行器的选项。但这并没有对性能造成太大影响,而且还保留了难以维护的重度反应式编程模型。

因此,我们决定删除它,并从头开始创建一个新的 Web 服务器,它只需为每个请求创建一个新的虚拟线程,并让 JVM 管理这些虚拟线程。一切都以阻塞模式重写!

基于虚拟线程
这意味着 JVM 会将每个虚拟线程的请求调度到可用的运载线程。

每当发生阻塞操作(如 IO 或网络调用)时,JVM 调度器就会卸载被阻塞的虚拟线程,找到另一个虚拟线程并将其挂载到空闲的载波线程上。这样,它的资源就会被重新使用。

当阻塞操作结束后,虚拟线程将被安排在第一个线程上继续执行。

这就是 "支持虚拟线程 "与 "基于虚拟线程 "之间的主要区别!

"副作用":使用 Helidon MP 创建的微配置文件应用程序的运行速度应该会大大加快,因为微配置文件应用程序接口主要是阻塞式的。


总之,有了 Helidon 4,您可以使用阻塞模式创建高性能应用程序,创建易于维护和调试的代码!