14. Reactor 反应堆模式

简介:

Reactor 反应堆模式是一种 事件驱动 的编程模型,核心是让框架(反应堆)统一管理事件,应用只需专注业务逻辑。常见于高性能网络编程(如 Redis、Nginx),用 “事件监听 + 回调处理” 解耦 I/O 操作,支持高并发。

工作流程(餐厅版)

  1. 初始化
    Reactor 启动,用 epoll 监控事件源(门口、餐桌)。
    → 类似经理上班,打开 “监控系统” 看有没有新客 / 服务需求。

  2. 事件监听
    Reactor 调用 epoll_wait 阻塞等待事件。
    → 经理坐着等,直到有人喊 “新客” 或 “加菜”。

  3. 事件分发
    事件发生(如门口有新客),Reactor 找到对应的 Handler(服务员)。
    → 经理喊:“小王,门口接新客!”

  4. 业务处理
    Handler 处理事件(接客、写数据、读请求)。
    → 服务员带新客入座、记录需求。

  5. 循环
    处理完事件,Reactor 继续监听下一轮事件。
    → 经理回去继续等,循环往复。

// Reactor 核心逻辑:监听事件 → 分发 → 处理
void Reactor::run() {
    while (!stop) {
        // 1. 等事件(epoll_wait)
        int n = epoll_wait(epfd, events, MAX_EVENTS, -1);
        if (n < 0) break;

        // 2. 遍历事件,分发处理
        for (int i = 0; i < n; i++) {
            int fd = events[i].data.fd;
            if (fd == listensock) {
                // 事件源:新连接 → 调用 accept 处理器
                acceptHandler();
            } else {
                // 事件源:普通 socket → 调用 读写处理器
                ioHandler(fd);
            }
        }
    }
}

// 处理新连接(Handler)
void Reactor::acceptHandler() {
    int clientfd = accept(listensock, ...);
    // 设为非阻塞 + ET 模式(配合 Reactor)
    setNonBlock(clientfd);
    epoll_ctl(epfd, EPOLL_CTL_ADD, clientfd, EPOLLIN | EPOLLET);
    // 关联业务处理器(如 HttpHandler)
    handlers[clientfd] = new HttpHandler(clientfd);
}

// 处理读写事件(Handler)
void Reactor::ioHandler(int fd) {
    auto handler = handlers[fd];
    // 读数据(非阻塞 + ET 需循环读)
    while (true) {
        int n = read(fd, buf, sizeof(buf));
        if (n < 0) {
            if (errno == EAGAIN) break; // 读完,退出循环
            // 处理错误,关闭连接
            close(fd);
            handlers.erase(fd);
            break;
        } else if (n == 0) {
            // 客户端关闭
            close(fd);
            handlers.erase(fd);
            break;
        }
        // 业务逻辑:解析请求、处理、响应
        handler->process(buf, n);
    }
}

关键特点(为什么高效?)

  • 解耦 I/O 与业务
    Reactor 负责 “等事件”,Handler 负责 “做业务”,代码不用混在一起。
  • 支持高并发
    一个 Reactor 可监控成千上万个事件源(如 socket),用 epoll 避免阻塞。
  • 事件驱动
    只有事件发生时才处理,不用轮询,资源利用率高。

5. 优缺点(什么时候用?)

优点:
  • 高并发友好:用 epoll 监控大量连接,单线程也能扛高并发。
  • 逻辑清晰:I/O 事件和业务处理分离,代码易维护。
  • 可扩展:新增业务(如 Redis 的 String/Hash 操作),只需加 Handler。
缺点:
  • 单线程瓶颈:若 Handler 处理耗时操作(如磁盘 IO),会阻塞整个 Reactor。
    → 解决:用 多 Reactor 模式(主 Reactor 负责接连接,子 Reactor 负责读写)。
  • ET 模式易错:需严格循环读写,否则丢数据(如忘记 EAGAIN 判断)。

6. 对比:Reactor vs 传统阻塞 I/O

模型传统阻塞 I/OReactor 模式
线程数一个连接一个线程(高并发时爆炸)单线程 / 少量线程(靠事件驱动)
阻塞问题线程阻塞在 read/write只有 Reactor 阻塞在 epoll_wait
适用场景连接少、逻辑简单高并发网络服务(如 Nginx、Redis)

总结:Reactor 是做什么的?

Reactor 反应堆模式,本质是让框架帮你 “等事件、分任务”,你只需要写 “事件发生后做什么”

  • 像餐厅经理:盯着所有事件(新客、加菜),有事就喊对应服务员处理。
  • 核心价值:用事件驱动替代轮询,把 “人等事” 变成 “事找人”,大幅提升高并发场景下的效率。

理解 Reactor 后,再看 Nginx、Redis 的网络模型,就会发现它们都是这套逻辑的延伸ovo

基于 Reactor 模式的 TCP 服务器框架设计

用 C++ 智能指针和 Channel/Connection 等组件,实现事件驱动的高并发网络编程,核心是 “解耦业务与网络 I/O”

1. 核心组件与分层

层级 / 组件作用
OS(最底层)提供 epoll 等系统调用,负责监控 fd 事件(如数据可读、新连接)。
epoll 层封装 epoll 操作,管理 fd 和事件,向上层(Connection)通知事件。
Connection 层每个 Connection 对应一个客户端连接,关联 Channel,管理读写缓冲区、状态。
Channel 层封装 fd 和事件(如 EPOLLIN/EPOLLOUT),是 Reactor 模式的 “事件载体”。
Listener监听新连接的特殊 Connection,收到新连接时创建普通 Connection
业务 / Protocol 层处理具体逻辑(如解析协议、业务计算),与网络 I/O 解耦。

2. 关键设计逻辑

(1)“Reactor 模式落地”
  • 事件驱动epoll 监控 fd 事件 → 触发 Channel → 回调业务逻辑。
  • 解耦:网络 I/O(epoll/Connection)和业务逻辑(Protocol)分离,RegisterHandler 注册回调实现解耦。
(2)“智能指针与对象管理”
  • 用 std::shared_ptr 管理 Connection/Channel,自动管理内存,避免泄漏。
  • connections unorder map:以 fd 为键,保存所有客户端连接,方便根据 fd 找到对应 Connection
(3)“Listener 职责”
  • 监听端口,收到新连接(epoll 检测到 EPOLLIN)时,创建新的 Connection 和 Channel,并加入 epoll 监控。

 多进程版 Reactor 负载均衡架构

Master 监听新连接并通过管道通知 Slave,Slave 继承 listensocket 处理实际连接,用 “管道事件 + Reactor” 解耦进程间协作,解决多进程竞争新连接问题,适合多核高并发场景。

多 Reactor 模式的高并发 服务器架构 (了解)

主从 Reactor 分工:Master 负责 “接新连接 + 扔队列 + 发通知”,Slave 负责 “收通知 + 取连接 + 处理 I/O”,用 eventfd 实现高效跨线程通信,适合高并发服务器。核心是 负载均衡 + 事件驱动

Channel.hpp

Common.hpp

Connection.hpp

Epoller.hpp

InetAddr.hpp

Listener.hpp

Main.cc 

Makefile

Mutex.hpp

NetCal.hpp

Protocol.hpp

Reactor.hpp

Socket.hpp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值