计算机性能的天花板在硬件,当所以 CPU 满负荷运行真正应用任务时,性能最高。如果 CPU 空转或很多时间用于进程/线程等系统管理任务,性能自然会有损失。1999 年提出了The C10K problem: 在 1GHZ CPU,2GB RAM,1Gbps  以太网配置,大概 1200 美金的计算机硬件已经可以同时支持 10,000 客户的并发访问。所需的工作都在操作系统和应用软件层面。30 年过去了,可以做个历史回顾和现状分析。

历史回顾

最开始的 Web Server 比如老版本的 Apache Server,每个请求对应一个进程。明显太慢。随后每个请求一个线程,虽然线程的数目可以大大超过进程数目,但是线程的切换通常在 1000 nanoseconds,浪费很多。用线程池,每个 active 的连接实用一个线程,大大提高了线程利用率。

通过使用操作系统的 epoll 非阻塞 I/O,2004 年的 Nginx 和 2009 年的 Node.js 把性能又提高了一个级别。Async IO on Linux: select, poll, and epoll 解释了 epoll。 This node document and What you should know to really understand the Node.js Event Loop 解释了 Node.js 的实现机制。

这些技术后面的关键是非阻塞 non-blocking, What the heck is the event loop anyway 给出了很好的解释。

2013 年有了 The C10M problem,即同时支持一千万的同时连接。The Secret To 10 Million Concurrent Connections 指出此时需要在操作系统内核更好的支持异步 IO 并尽可能让应用程序来掌控 CPU 以及管理内存的使用。

Japronto 项目用 C 语言写了 Python 的 HTTP 工具,在 2017 年达到每秒可以服务 120 万简单请求。

应用程序优化

三种 Thread Pools

ZIO Thread Pool

Improving Akka Dispatchers

Java Fiber

做好三件事:

  • 配置正确的 Thread Pool
  • 端到端非阻塞
  • 使用更轻量的 Fiber

这篇 2019 年的消息Oracle stops work on ADBA 确认了 Oracle 认为 Java 的可扩展性方向是 fiber,而不是异步。