Tomcat 11:虚拟线程是换自行车,还是把大门敞开?
JEP 444 对虚拟线程的定位很清楚:它适合 thread-per-request 的服务器应用,尤其是大量任务在等待 I/O 的场景;虚拟线程不该池化,真正昂贵的资源要单独限流。Tomcat 11.0.25 的官方文档能确认 Servlet 6.1、Pages 4.0 和当前版本,但我在首页索引里没有看到“默认使用虚拟线程”的承诺。原帖把 StandardVirtualThreadExecutor、10 万并发和 100,000~200,000 QPS 写成了必然结果,至少还需要配置细节和压测脚本。
虚拟线程最容易被误读成“把 200 个 OS 线程换成 100 万个线程,机器就快十倍”。这相当于把银行柜台前的大厅扩建到一百万平方米,却只保留二十个窗口。前台确实可以不挤了,客户全堵在数据库连接池上,系统只是把等待从 Tomcat 搬到了数据库。maxThreads、executor、maxConnections、acceptCount、HikariCP、锁等待、CPU、GC 和下游 timeout 必须一起看。
JEP 还留了一个老坑:虚拟线程在 synchronized 保护的区域里,或进入 native/FFM 调用时,可能 pinned,无法及时从 carrier 线程卸载。synchronized 保护一段内存操作通常没问题,问题是把网络 I/O、长时间锁等待也一起塞进 monitor。Tomcat 自己是否“把所有 synchronized 都换成 ReentrantLock”不能凭标题判断,应该查对应版本源码和 changelog。
所以开头的比喻要改一改:虚拟线程给 Tomcat 换上轻量踏板,数据库、第三方 API 和本机 native 库仍是道路。若要做生产决策,压测至少同时报 p50/p95/p99、吞吐、CPU、RSS、GC、数据库连接等待时间和 pinned 持续时间。指标不全的“革命”通常只是发布会姿势。
来源:
- https://openjdk.org/jeps/444
- https://tomcat.apache.org/tomcat-11.0-doc/