3.5 异步I/O与其他模型的对比

31 阅读2分钟

这一小节是第三章的亮点之一,朴灵作者把Node的异步I/O模型与其他主流并发模型进行横向对比,帮助我们理解Node的定位:它不是万能的,但在大多Web场景下性价比最高

作者主要对比了以下几种模型:

1. 传统阻塞I/O模型(多线程/多进程,如Apache早期、PHP、Java Servlet)

  • 每个连接一个线程 → 线程开销大、上下文切换频繁。
  • 优点:编程简单(同步代码)。
  • 缺点:并发几千就资源耗尽。
  • Node胜出:单线程事件驱动,轻松上万并发。

2. Nginx的事件驱动模型

  • 和Node最像:都用事件循环 + 非阻塞I/O(epoll/kqueue)。
  • Nginx用C语言实现,多进程 + 事件循环(每个worker一个事件循环)。
  • 对比:
    • 相似:高并发、低资源。
    • 不同:Nginx静态文件/反向代理更极致(零拷贝等优化),Node更灵活(JS动态逻辑)。
  • 作者结论:Node适合业务逻辑复杂的服务,Nginx适合纯代理/静态服务。

3. Java的NIO(New I/O)模型

  • Java从1.4起支持非阻塞I/O(Selector + Channel)。
  • 但Java生态多用线程池(如Tomcat的线程池 + NIO)。
  • 对比:Node天生事件驱动,JS单线程无锁;Java多线程编程复杂,容易死锁/竞争。

4. Go语言的Goroutine模型(当时新兴)

  • 轻量级用户态线程(goroutine),千千万万不怕。
  • 调度器自动在少量OS线程上复用。
  • 对比:
    • Go并发更细粒度,适合CPU密集 + I/O。
    • Node不适合CPU密集(单线程计算阻塞事件循环)。
  • 作者预言:Go会是Node的有力竞争者(事实如此,现在很多高性能服务用Go)。

其他提及

  • select/poll vs epoll/IOCP:回顾前文,Node通过libuv统一这些底层差异。

作者总结:没有银弹。Node在I/O密集型(如Web API、实时应用)性价比最高;CPU密集用Go/C++;静态服务用Nginx。