事件驱动模型
事件驱动是高性能服务器的架构范式:不等待,有事件才干活。面试主线:Reactor 模式、线程模型、经典实践。
Reactor 模式
Reactor: 事件分发, 处理不阻塞
- Reactor:事件循环 + 分发(谁有事件就派给谁)
- Acceptor:处理连接建立
- Handler:处理业务(读、算、写)
- 核心:事件驱动 + 非阻塞 IO + 回调
线程模型演进
| 模型 | 结构 | 特点 |
|---|---|---|
| 单 Reactor 单线程 | 一个线程全包 | 简单(Redis),CPU 密集不行 |
| 单 Reactor 多线程 | 分发单线程 + 业务线程池 | 分发是瓶颈 |
| 主从 Reactor 多线程 | 主 Reactor 管连接,从 Reactor 管 IO,业务线程池 | 生产标准(Netty) |
Netty 模型(Java 必考):Boss Group(accept)+ Worker Group(IO 事件)+ 业务线程池。连接和 IO 分流,多核利用。
Proactor:异步 IO
| 模式 | 数据读取 | 谁等待 |
|---|---|---|
| Reactor | 通知“可读了”,应用自己读 | 应用读(同步读) |
| Proactor | 内核读完,通知“数据好了” | 内核读(异步 IO) |
- Proactor 减少一次“读”的系统调用,但依赖 OS 异步 IO 支持(Windows IOCP 成熟,Linux AIO 支持弱)
- 实际工程:Reactor 是主流(跨平台一致),Linux 高并发事实标准
经典实践
| 系统 | 模型 |
|---|---|
| Redis | 单 Reactor 单线程(命令微秒级,够用) |
| Nginx | 多进程 + 事件循环(每 worker 一个 Reactor) |
| Netty | 主从 Reactor 多线程 |
| Node.js | 单线程事件循环 + 线程池(libuv) |
与协程的关系:事件驱动是“回调式”并发,协程是“顺序写法的事件驱动”(见 Python asyncio 篇:事件循环本质是 Reactor)。
面试追问
- Reactor 是什么? 事件分发器:连接/读/写事件派给对应处理器。非阻塞 + 回调
- 主从 Reactor? 主管连接、从管 IO、业务线程池。Netty 标准,多核利用
- Reactor 和 Proactor? Reactor 通知“可读了”自己读,Proactor 内核读完再通知。Reactor 跨平台主流
- Redis 为什么单线程 Reactor 够? 命令内存操作微秒级,单线程免锁。CPU 密集场景才需要多线程
- 协程和事件驱动? 协程是事件驱动的顺序化封装(asyncio 的事件循环就是 Reactor)