如果把现有 Web 服务迁移到虚拟线程,你会先选哪些接口试点?还需要限制并发吗?
我的判断
我会先试点线程长期阻塞在网络或数据库上的接口;虚拟线程能减少线程等待成本,但数据库、下游和 CPU 仍必须限流。
首批会选代码以同步阻塞为主、并发高、单请求 CPU 很少的查询接口,例如聚合多个 HTTP/RPC 的页面。纯计算、长时间持锁和已经成熟的响应式链路不急着迁。
迁移前记录平台线程数、队列等待、吞吐、P99 和下游并发。改成每请求虚拟线程后,代码可以保留同步写法,但会重点排查 synchronized 中执行阻塞调用、native 调用等 pinning;用 JFR 看固定载体线程是否被占住。
并发限制仍然存在:连接池只有 100 个连接,就用信号量或池本身把数据库并发限制在 100 左右;不能因为可以创建十万个虚拟线程,就同时打十万个请求给下游。ThreadLocal 的数量和内容也要检查,因为每个虚拟线程一份上下文仍会占内存。
我会灰度一个低风险接口,对比资源和延迟后再扩大,而不是一次把所有 executor 删除。虚拟线程解决的是等待线程成本,不解决容量规划。
思路拆解问题分析
判断是否适合虚拟线程,我看的是 阻塞等待占比,不是接口名字。等待越多、调用栈越适合同步写法,收益越明显;CPU 已经跑满的服务换线程模型不会凭空增加算力。