【系统架构设计百科】线程模型:从 thread-per-request 到协程

💡 原文中文,约29000字,阅读约需69分钟。
📝

内容提要

2024年初,某电商平台在大促期间遇到性能事故,Java服务在并发连接数超过2万时响应延迟显著增加。问题源于线程模型不当,导致内存耗尽和频繁的上下文切换。文章探讨了不同线程模型(如每请求一线程、Reactor、Proactor、协程)的性能边界及其对架构决策的影响,强调选择合适模型以应对高并发场景的重要性。

🎯

关键要点

  • 2024年初,某电商平台在大促期间的Java服务在并发连接数超过2万时,响应延迟显著增加,问题源于线程模型不当。
  • 每请求一线程模型的优点是代码顺序执行,调试容易,但在高并发场景下会导致内存耗尽和上下文切换开销。
  • I/O多路复用是解决C10K问题的第一步,通过一个线程监听多个文件描述符,减少了线程数量。
  • Reactor模式是基于I/O多路复用的事件驱动架构,能够处理高并发连接,但要求所有操作必须是异步的。
  • Proactor模式与Reactor的区别在于I/O操作的执行方式,Proactor由内核完成I/O操作,减少了应用程序的负担。
  • 协程和绿色线程旨在恢复顺序编程的体验,同时保持高并发能力,Go的goroutine是协程模型的成功实现。
  • Java 21引入的虚拟线程旨在让每个并发任务拥有自己的线程,但不再受操作系统线程的开销限制。
  • Rust的async/await通过惰性计算和编译期状态机实现异步编程,提供了更高的控制精度。
  • 线程模型的选择会深刻影响系统的架构设计,必须根据实际的并发负载做出合理的决策。

延伸问答

电商平台在大促期间遇到的性能事故是什么原因导致的?

性能事故是由于线程模型不当,导致内存耗尽和频繁的上下文切换。

什么是每请求一线程模型,它的优缺点是什么?

每请求一线程模型为每个客户端连接创建独立的操作系统线程,优点是代码顺序执行,调试容易;缺点是在高并发场景下会导致内存耗尽和上下文切换开销。

Reactor模式与Proactor模式有什么区别?

Reactor模式由应用程序在收到就绪通知后自行进行I/O操作,而Proactor模式则由操作系统内核完成I/O操作,应用程序只需处理完成的结果。

协程的优势是什么?

协程旨在恢复顺序编程的体验,同时保持高并发能力,能够在较低的内存开销下处理大量并发连接。

Java 21中的虚拟线程有什么特点?

Java 21中的虚拟线程允许每个并发任务拥有自己的线程,但不再受操作系统线程的开销限制,能够自动挂起阻塞操作。

选择合适的线程模型对系统架构设计有什么影响?

线程模型的选择会深刻影响系统的架构设计,必须根据实际的并发负载做出合理的决策,错误的选择可能导致性能瓶颈。

➡️

继续阅读