共计 1838 个字符,预计需要花费 5 分钟才能阅读完成。
介绍
Loom
我的项目的指标是为 JRE 带来易于应用、高吞吐、轻量级并发。Loom
的一个个性是虚构线程。在本文中,咱们将摸索在 Tomcat 上部署的简略 wen 利用上应用虚构贤臣更意味着什么。
高吞吐 / 轻量级
第一个试验是比拟应用 Tomcat 规范线程池的开销和应用虚构线程的执行器的开销。测试环境在本文最初给出。应用每秒均匀申请数查看了不同响应大小和申请并发性的性能。后果如下图所示。
结果表明,通常,创立新的虚构线程来解决申请的开销小于从线程池获取平台线程的开销。在线程池测试中看到的一个意外后果是,对于较小的响应主体,2 个并发用户每秒产生的均匀申请数比单个用户少。考察发现,在传递给 Executor 的工作和 Executor 调用工作的 run()
办法之间产生了额定的提早。这一差别在 4 个并发用户中缩小,在 8 个并发用户简直隐没。
当并发工作多于可用的处理器核时,在高并发级别,虚构线程执行器再次显示出更高的性能。这在应用较小响应体的测试中更为显著。依据图中的测试,(译者注:响应体小于 4k 时,并发越大越显著。小于 16K 是会有一定量的进步。再大一些的话和规范线程池差异不大了。
易于应用
第二个试验将应用规范线程池的 Servlet 异步 I / O 取得的性能与应用基于虚构线程的执行器的简略阻塞 I / O 取得的成果进行了比拟。虚构线程的潜在益处是简略。与等效的 Servlet 异步读写相比,阻塞读写要简略得多,特地是在思考错误处理时。
Servlet 异步 I / O 通常用于拜访响应有显著提早的某些内部服务。测试 web 应用程序在 Service 类中对此进行了模仿。与基于虚构线程的执行器一起应用的 Servlet 以阻塞形式拜访服务,而与规范线程池一起应用的 Servlet 应用 Servlet 异步 API 拜访服务。没有波及任何网络 IO,但这不应该影响后果。
不出所料,最后的测试显示,阻塞办法和异步办法之间没有可测量的差别,因为计时次要由 5 秒提早管制。为了在没有提早影响的状况下摸索差别,将提早缩小为零,并执行了一组与吞吐量测试相似的测试。后果如下图所示:
咱们再次看到,虚构线程通常性能更高,在低并发和并发超过可用于测试的处理器内核数量时,差别最为显著。
剖析
基于虚构线程的执行器和 Tomcat 的规范线程池之间的差别并不像从上图中首次看到的那样显著。这些测试旨在查看与每种办法相干的开销,并不代表理论应用程序。在理论利用中,与实现申请所需的工夫相比,测试中显示的差别可能微不足道。
第一个因素:Tomcat 的规范线程池和基于虚构线程的执行器之间性能差别的 次要因素是线程池队列增加和删除工作的竞争。通过优化 Tomcat 应用的以后实现,能够缩小规范线程池队列中的锁竞争,并进步吞吐量。
第二个因素:上下文切换。这可能是第二个试验中呈现的性能差别的一种解释,因为虚构线程的上下文切换比规范线程池中的线程的老本更低,因而并发性超过了可用的处理器内核数。
论断
应用基于虚构线程的执行器是 Tomcat 规范线程池的可行代替计划。就容器开销而言,切换到虚构线程执行器的益处微不足道。
经验阻塞诸的 Web 应用程序(比方 Tomcat 上经典的 Spring MVC 利用),并且尚未切换到 Servlet 异步 API,响应式编程或其余异步 API,应该通过切换到基于虚构线程的执行器来看到一些可扩展性的改良。依据 Web 应用程序,能够实现这些改良,而不会更改 Web 利用程序代码。切换到应用 Servlet 异步 API、响应式编程或其余异步 API 的 Web 应用程序不太可能通过切换到基于虚构线程的执行器来察看到可测量的差别(侧面或负面),除非单机需承担的 QPS 特地大。
从久远来看,虚构线程的最大益处仿佛是更简略的利用程序代码。以后须要应用 Servlet 异步 API、反应式编程或其余异步 API 的一些用例将可能应用阻塞 IO 和虚构线程来满足。对此须要留神的是,应用程序通常须要对不同的内部服务进行屡次调用。这是虚构线程最无效的并行实现,尽管 Project Reactor 等框架为此提供了一流的反对,但 JRE 的同类解决方案(结构化并发)仍处于孵化器阶段,仅旨在协调多个Future
,而不是以最不便的形式互相申明或组合它们。
最初,Loom
我的项目仍处于预览模式。当初思考在生产环境中应用虚构线程还为时过早,但当初是将 Loom
我的项目和虚构线程纳入布局的时候了,这样当 JRE 中正式有虚构线程时,您就能够做好筹备了。
测试环境
未译,原文地址: https://spring.io/blog/2023/0…