虚拟线程能不能让普通的 Spring MVC 追上 WebFlux?吞吐、延迟、内存各是多少?线程池 200 个线程的吞吐上限怎么算?这篇在本机用真实的 HTTP 下游,把三种写法放在同一份负载下比较。
启动后空闲 RSS 236 MB;单个请求 → 200 ok 并发 100:两轮吞吐 914 / 924 请求/秒;p50 111.1 / 110.9 ms;p99 121.4 / 118.1 ms;错误 0 / 0;RSS 369 MB;peakPlatformThreads=221 livePlatformThreads=221 heapUsedMB=25 并发 1000:两轮吞吐 1997 / 1946 请求/秒;p50 549.5 / 557.6 ms;p99 586.5 / 574.1 ms;错误 0 / 0;RSS 439 MB;peakPlatformThreads=414 livePlatformThreads=414 heapUsedMB=36 并发 3000:两轮吞吐 2270 / 2312 请求/秒;p50 1670.0 / 1659.5 ms;p99 1772.4 / 1715.7 ms;错误 0 / 0;RSS 462 MB;peakPlatformThreads=436 livePlatformThreads=436 heapUsedMB=36
吞吐被线程数封顶(200 ÷ 100 ms ≈ 2000),并发超过线程数只排队。
启动后空闲 RSS 243 MB;单个请求 → 200 ok 并发 100:两轮吞吐 922 / 933 请求/秒;p50 110.8 / 109.6 ms;p99 116.4 / 116.9 ms;错误 0 / 0;RSS 370 MB;peakPlatformThreads=31 livePlatformThreads=31 heapUsedMB=25 并发 1000:两轮吞吐 9037 / 9229 请求/秒;p50 112.8 / 109.4 ms;p99 126.9 / 123.3 ms;错误 0 / 0;RSS 688 MB;peakPlatformThreads=31 livePlatformThreads=31 heapUsedMB=49 并发 3000:两轮吞吐 14970 / 12465 请求/秒;p50 169.0 / 207.9 ms;p99 1319.4 / 2642.9 ms;错误 2 / 0;RSS 1161 MB;peakPlatformThreads=31 livePlatformThreads=31 heapUsedMB=84
阻塞代码不改就拿到接近 WebFlux 的吞吐,内存更高。
启动后空闲 RSS 240 MB;单个请求 → 200 ok
并发 100:两轮吞吐 922 / 927 请求/秒;p50 111.8 / 110.7 ms;p99 121.0 / 123.2 ms;错误 0 / 0;RSS 367 MB;peakPlatformThreads=18 livePlatformThreads=18 heapUsedMB=15
并发 1000:两轮吞吐 9052 / 9179 请求/秒;p50 111.7 / 110.7 ms;p99 125.0 / 126.0 ms;错误 0 / 0;RSS 375 MB;peakPlatformThreads=18 livePlatformThreads=18 heapUsedMB=17
并发 3000:两轮吞吐 19622 / 12919 请求/秒;p50 118.3 / 129.7 ms;p99 1631.1 / 4541.7 ms;错误 114 / 0;RSS 522 MB;peakPlatformThreads=18 livePlatformThreads=18 heapUsedMB=24 应用内的异常={WebClientRequestException <- SocketException: Connection reset=109}吞吐与虚拟线程同量级,内存更低,代价是响应式写法。