Muduo:(0) 架构与接口总览

一、项目概述

1.1 项目简介

mymuduo 是一个基于 Reactor 模式的高性能 C++ 网络库,基于陈硕的 muduo 网络库进行 C++ 重构。它提供了简洁的 API,支持 TCP 服务器和客户端开发,具有以下特点:

  • 事件驱动:基于 epoll 的高效 I/O 多路复用
  • 多线程支持:主从 Reactor 模式,充分利用多核 CPU
  • 异步编程:基于回调的异步编程模型

1.2 核心特性

特性 说明
Reactor 模式 事件驱动的并发模型
One Loop Per Thread 每个线程一个事件循环
非阻塞 I/O 全程非阻塞操作
连接管理 自动管理连接生命周期
缓冲区管理 高效的数据缓冲机制
日志系统 灵活的日志记录

1.3 项目结构

复制代码
mymuduo/
├── include/              # 头文件目录
│   ├── EventLoop.h
│   ├── Channel.h
│   ├── Poller.h
│   ├── EPollPoller.h
│   ├── TcpServer.h
│   ├── TcpConnection.h
│   ├── Acceptor.h
│   ├── EventLoopThreadPool.h
│   ├── EventLoopThread.h
│   ├── Buffer.h
│   ├── Logger.h
│   ├── LogStream.h
│   ├── Thread.h
│   ├── Socket.h
│   ├── InetAddress.h
│   ├── Timestamp.h
│   ├── NonCopyable.h
│   ├── CurrentThread.h
│   └── Callbacks.h
├── src/                  # 源文件目录
│   ├── EventLoop.cpp
│   ├── Channel.cpp
│   ├── Poller.cpp
│   ├── EPollPoller.cpp
│   ├── DefaultPoller.cpp
│   ├── TcpServer.cpp
│   ├── TcpConnection.cpp
│   ├── Acceptor.cpp
│   ├── EventLoopThreadPool.cpp
│   ├── EventLoopThread.cpp
│   ├── Logger.cpp
│   ├── LogStream.cpp
│   ├── Thread.cpp
│   ├── Socket.cpp
│   ├── InetAddress.cpp
│   ├── Timestamp.cpp
│   └── CurrentThread.cpp
├── example/              # 示例代码
│   └── EchoServer.cpp
├── readme/               # 文档目录
│   └── *.md
└── build/                # 构建目录

二、整体架构设计

2.1 架构总览

mymuduo 采用分层架构设计:

复制代码
+--------------------------------------------------+
|                   应用层                          |
|            (用户代码 / EchoServer)               |
+--------------------------------------------------+
                        |
+--------------------------------------------------+
|                   服务器层                        |
|              TcpServer / TcpConnection           |
+--------------------------------------------------+
                        |
+--------------------------------------------------+
|                   事件层                          |
|         EventLoop / Channel / Poller             |
+--------------------------------------------------+
                        |
+--------------------------------------------------+
|                   工具层                          |
|    Buffer / Logger / Thread / Socket / Timestamp |
+--------------------------------------------------+

2.2 Reactor 模式

mymuduo 实现了 Reactor 模式,核心组件包括:

复制代码
+--------------------------------------------------+
|                   Reactor 模式                    |
+--------------------------------------------------+
|                                                   |
|  +-------------+     +-------------+              |
|  |   Handle    |---->|  Synchronous|              |
|  |  (fd)       |     |  Event Demux|              |
|  +-------------+     |  (Poller)   |              |
|                      +-------------+              |
|                             |                     |
|                             v                     |
|                      +-------------+              |
|                      |  Initiation |              |
|                      |  Dispatcher |              |
|                      |  (EventLoop)|              |
|                      +-------------+              |
|                             |                     |
|                             v                     |
|                      +-------------+              |
|                      |Event Handler|              |
|                      |  (Channel)  |              |
|                      +-------------+              |
|                             |                     |
|                             v                     |
|                      +-------------+              |
|                      |  Callbacks  |              |
|                      +-------------+              |
|                                                   |
+--------------------------------------------------+

2.3 主从 Reactor 线程模型

复制代码
+--------------------------------------------------+
|                主从 Reactor 模型                  |
+--------------------------------------------------+
|                                                   |
|  +------------------+                             |
|  |    mainReactor   |  (主线程)                   |
|  |    (baseLoop)    |                             |
|  +--------+---------+                             |
|           |                                       |
|           | 新连接                                |
|           v                                       |
|  +------------------+                             |
|  |    Acceptor      |                             |
|  +--------+---------+                             |
|           |                                       |
|           | 分发连接                              |
|           v                                       |
|  +--------+--------+--------+--------+           |
|  |        |        |        |        |           |
|  v        v        v        v        v           |
| +----+  +----+  +----+  +----+  +----+          |
| |sub |  |sub |  |sub |  |sub |  |sub |          |
| |Reactor|Reactor|Reactor|Reactor|Reactor|       |
| +----+  +----+  +----+  +----+  +----+          |
|   |        |        |        |        |          |
|   v        v        v        v        v          |
| +----+  +----+  +----+  +----+  +----+          |
| |Conn|  |Conn|  |Conn|  |Conn|  |Conn|          |
| +----+  +----+  +----+  +----+  +----+          |
|                                                   |
+--------------------------------------------------+

2.4 数据流向

复制代码
接收数据流:
+----------+     +----------+     +----------+     +----------+
|  Client  |---->|  socket  |---->|  Channel |---->| EventLoop|
+----------+     +----------+     +----------+     +----------+
                                                        |
                                                        v
+----------+     +----------+     +----------+     +----------+
| 用户回调  |<----|MessageCb |<----|inputBuffer|<---|handleRead|
+----------+     +----------+     +----------+     +----------+

发送数据流:
+----------+     +----------+     +----------+     +----------+
| 用户代码  |---->|  send()  |---->|outputBuffer|-->|handleWrite|
+----------+     +----------+     +----------+     +----------+
                                                        |
                                                        v
+----------+     +----------+     +----------+     +----------+
|  Client  |<----|  socket  |<----|  Channel |<----| EventLoop|
+----------+     +----------+     +----------+     +----------+

三、技术选型

3.1 核心技术

技术 选择 原因
I/O 多路复用 epoll Linux 高性能实现
线程模型 std::thread C++11 标准,跨平台
回调机制 std::function 类型安全,灵活
智能指针 std::shared_ptr 自动内存管理
原子操作 std::atomic 无锁编程支持

3.2 系统调用

系统调用 用途
epoll_create1 创建 epoll 实例
epoll_ctl 控制 epoll 实例
epoll_wait 等待事件
eventfd 线程间通信
accept4 接受连接
readv 分散读取
sendfile 零拷贝发送

3.3 设计模式

模式 应用场景
Reactor 事件驱动架构
RAII 资源管理
策略模式 Poller 抽象
观察者模式 回调机制
工厂模式 Poller 创建

四、模块职责与协作

4.1 核心模块

4.1.1 EventLoop

职责

  • 事件循环管理
  • 任务调度
  • 线程绑定

协作关系

复制代码
EventLoop
    |
    +-- Poller (I/O 多路复用)
    |
    +-- Channel (事件分发)
    |
    +-- wakeupFd (线程唤醒)
4.1.2 Channel

职责

  • 封装 fd 和事件
  • 管理事件回调
  • 事件状态跟踪

协作关系

复制代码
Channel
    |
    +-- EventLoop (所属循环)
    |
    +-- Poller (事件注册)
    |
    +-- TcpConnection (回调设置)
4.1.3 Poller / EPollPoller

职责

  • I/O 多路复用
  • Channel 管理
  • 事件轮询

协作关系

复制代码
Poller (抽象基类)
    |
    +-- EPollPoller (epoll 实现)
    |
    +-- ChannelMap (fd -> Channel)
4.1.4 TcpServer

职责

  • 服务器管理
  • 连接管理
  • 回调管理

协作关系

复制代码
TcpServer
    |
    +-- Acceptor (接受连接)
    |
    +-- EventLoopThreadPool (线程池)
    |
    +-- ConnectionMap (连接管理)
4.1.5 TcpConnection

职责

  • 连接状态管理
  • 数据收发
  • 事件处理

协作关系

复制代码
TcpConnection
    |
    +-- Socket (套接字)
    |
    +-- Channel (事件通道)
    |
    +-- Buffer (数据缓冲)
4.1.6 Acceptor

职责

  • 监听 socket 管理
  • 接受新连接
  • 回调通知

协作关系

复制代码
Acceptor
    |
    +-- Socket (监听 socket)
    |
    +-- Channel (监听事件)
    |
    +-- TcpServer (新连接回调)
4.1.7 EventLoopThreadPool

职责

  • 线程池管理
  • 负载均衡
  • EventLoop 分发

协作关系

复制代码
EventLoopThreadPool
    |
    +-- EventLoopThread[] (IO 线程)
    |
    +-- baseLoop (主循环)
4.1.8 Buffer

职责

  • 数据缓冲
  • 高效读写
  • 自动扩容

协作关系

复制代码
Buffer
    |
    +-- TcpConnection (输入/输出缓冲)
    |
    +-- readv (分散读取)

4.2 模块依赖图

复制代码
                    +----------------+
                    |   TcpServer    |
                    +-------+--------+
                            |
            +---------------+---------------+
            |               |               |
    +-------v-------+ +-----v-----+ +-------v-------+
    |   Acceptor    | |Thread Pool| | ConnectionMap |
    +-------+-------+ +-----+-----+ +-------+-------+
            |               |               |
            |               |               |
    +-------v-------+       |       +-------v-------+
    |   Socket      |       |       | TcpConnection |
    +-------+-------+       |       +-------+-------+
            |               |               |
            v               v               v
    +----------------+ +-----------+ +---------------+
    |    Channel     | |EventLoop  | | Buffer        |
    +----------------+ |   Thread  | | Socket        |
            |          +-----------+ | Channel       |
            v                |       +---------------+
    +----------------+       |
    |    EventLoop   |<------+
    +----------------+
            |
            v
    +----------------+
    |     Poller     |
    +----------------+

五、项目使用

5.1 Echo 服务器示例

cpp 复制代码
#include "TcpServer.h"
#include "EventLoop.h"
#include "LogStream.h"
#include <iostream>

using namespace mymuduo;

class EchoServer {
public:
    EchoServer(EventLoop *loop, const InetAddress &addr, const std::string &name)
        : server_(loop, addr, name), loop_(loop) {
        
        server_.setConnectionCallback(
            std::bind(&EchoServer::onConnection, this, std::placeholders::_1));
        server_.setMessageCallback(
            std::bind(&EchoServer::onMessage, this, 
                      std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
        server_.setThreadNum(3);
    }

    void start() { server_.start(); }

private:
    void onConnection(const TcpConnectionPtr &conn) {
        if (conn->connected()) {
            LOG_INFO << "Connection UP : " << conn->peerAddress().toIpPort();
        } else {
            LOG_INFO << "Connection DOWN : " << conn->peerAddress().toIpPort();
        }
    }

    void onMessage(const TcpConnectionPtr &conn, Buffer *buf, Timestamp time) {
        std::string msg = buf->retrieveAllAsString();
        conn->send(msg);
    }

    TcpServer server_;
    EventLoop *loop_;
};

int main() {
    g_logger = new Logger();
    g_logger->SetLogLevel(kInfo);
    
    EventLoop loop;
    InetAddress addr(8080);
    EchoServer server(&loop, addr, "EchoServer");
    
    std::cout << "SERVER START..." << std::endl;
    server.start();
    loop.loop();
    
    delete g_logger;
    return 0;
}

5.2 使用流程

复制代码
+--------------------------------------------------+
|                服务器使用流程                      |
+--------------------------------------------------+
|                                                   |
|  1. 初始化日志系统                                 |
|     g_logger = new Logger();                      |
|     g_logger->SetLogLevel(kInfo);                 |
|                                                   |
|  2. 创建事件循环                                   |
|     EventLoop loop;                               |
|                                                   |
|  3. 创建服务器                                     |
|     TcpServer server(&loop, addr, "name");        |
|                                                   |
|  4. 设置回调                                       |
|     server.setConnectionCallback(...);            |
|     server.setMessageCallback(...);               |
|                                                   |
|  5. 设置线程数                                     |
|     server.setThreadNum(4);                       |
|                                                   |
|  6. 启动服务器                                     |
|     server.start();                               |
|                                                   |
|  7. 运行事件循环                                   |
|     loop.loop();                                  |
|                                                   |
+--------------------------------------------------+

六、API 接口

6.1 TcpServer API

6.1.1 构造函数
cpp 复制代码
TcpServer(EventLoop* loop,
          const InetAddress& listenAddr,
          const std::string& nameArg,
          Option option = kNoReusePort);

参数说明

参数 类型 说明
loop EventLoop* 主事件循环
listenAddr const InetAddress& 监听地址
nameArg const std::string& 服务器名称
option Option 端口重用选项

示例

cpp 复制代码
EventLoop loop;
InetAddress addr(8080, "0.0.0.0");
TcpServer server(&loop, addr, "MyServer");
6.1.2 设置回调
cpp 复制代码
void setConnectionCallback(const ConnectionCallback& cb);
void setMessageCallback(const MessageCallback& cb);
void setWriteCompleteCallback(const WriteCompleteCallback& cb);
void setThreadInitCallback(const ThreadInitCallback& cb);

回调类型定义

cpp 复制代码
typedef std::function<void (const TcpConnectionPtr&)> ConnectionCallback;
typedef std::function<void (const TcpConnectionPtr&, Buffer*, Timestamp)> MessageCallback;
typedef std::function<void (const TcpConnectionPtr&)> WriteCompleteCallback;
typedef std::function<void(EventLoop*)> ThreadInitCallback;
6.1.3 启动服务器
cpp 复制代码
void setThreadNum(int numThreads);  // 设置线程数
void start();                        // 启动服务器

6.2 TcpConnection API

6.2.1 基本信息
cpp 复制代码
EventLoop* getLoop() const;
const std::string& name() const;
const InetAddress& localAddress() const;
const InetAddress& peerAddress() const;
bool connected() const;
6.2.2 数据发送
cpp 复制代码
void send(const std::string &buf);
void sendFile(int fileDescriptor, off_t offset, size_t count);
void shutdown();

参数说明

方法 说明
send 发送字符串数据
sendFile 零拷贝发送文件
shutdown 半关闭连接
6.2.3 回调设置
cpp 复制代码
void setConnectionCallback(const ConnectionCallback &cb);
void setMessageCallback(const MessageCallback &cb);
void setWriteCompleteCallback(const WriteCompleteCallback &cb);
void setCloseCallback(const CloseCallback &cb);
void setHighWaterMarkCallback(const HighWaterMarkCallback &cb, size_t highWaterMark);

6.3 EventLoop API

6.3.1 事件循环控制
cpp 复制代码
void loop();  // 启动事件循环
void quit();  // 退出事件循环
6.3.2 任务调度
cpp 复制代码
void runInLoop(Functor cb);   // 在事件循环中执行
void queueInLoop(Functor cb); // 加入任务队列
6.3.3 Channel 管理
cpp 复制代码
void updateChannel(Channel* channel);
void removeChannel(Channel* channel);
bool hasChannel(Channel* channel);

6.4 Buffer API

6.4.1 数据读取
cpp 复制代码
size_t readableBytes() const;
const char *peek() const;
void retrieve(size_t len);
void retrieveAll();
std::string retrieveAllAsString();
std::string retrieveAsString(size_t len);
6.4.2 数据写入
cpp 复制代码
size_t writableBytes() const;
char *beginWrite();
void append(const char *data, size_t len);
6.4.3 I/O 操作
cpp 复制代码
ssize_t readFd(int fd, int *saveErrno);
ssize_t writeFd(int fd, int *saveErrno);

6.5 InetAddress API

cpp 复制代码
explicit InetAddress(uint16_t port = 0, std::string ip = "127.0.0.1");
std::string toIp() const;
std::string toIpPort() const;
uint16_t toPort() const;
const sockaddr_in *getSockAddr() const;

七、外部系统集成指南

7.1 HTTP 服务器集成

cpp 复制代码
#include "TcpServer.h"
#include "EventLoop.h"

class HttpServer {
public:
    HttpServer(EventLoop* loop, const InetAddress& addr)
        : server_(loop, addr, "HttpServer") {
        server_.setMessageCallback(
            std::bind(&HttpServer::onRequest, this, 
                      std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    }

private:
    void onRequest(const TcpConnectionPtr& conn, Buffer* buf, Timestamp) {
        // 解析 HTTP 请求
        std::string request = buf->retrieveAllAsString();
        
        // 生成 HTTP 响应
        std::string response = "HTTP/1.1 200 OK\r\n"
                               "Content-Type: text/html\r\n"
                               "Content-Length: 13\r\n"
                               "\r\n"
                               "Hello, World!";
        conn->send(response);
        conn->shutdown();
    }

    TcpServer server_;
};

7.2 RPC 框架集成

cpp 复制代码
class RpcServer {
public:
    RpcServer(EventLoop* loop, const InetAddress& addr)
        : server_(loop, addr, "RpcServer") {
        server_.setMessageCallback(
            std::bind(&RpcServer::onMessage, this, 
                      std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    }

private:
    void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp) {
        // 解析 RPC 请求
        while (buf->readableBytes() >= 4) {
            int32_t len = ntohl(*reinterpret_cast<const int32_t*>(buf->peek()));
            if (buf->readableBytes() < 4 + len) break;
            
            buf->retrieve(4);
            std::string request(buf->peek(), len);
            buf->retrieve(len);
            
            // 处理 RPC 调用
            std::string response = processRpc(request);
            
            // 发送响应
            int32_t respLen = htonl(response.size());
            conn->send(std::string(reinterpret_cast<char*>(&respLen), 4) + response);
        }
    }

    std::string processRpc(const std::string& request) {
        // RPC 处理逻辑
        return "result";
    }

    TcpServer server_;
};

7.3 消息队列集成

cpp 复制代码
class MessageQueueBridge {
public:
    MessageQueueBridge(TcpServer* server) : server_(server) {
        server_->setMessageCallback(
            std::bind(&MessageQueueBridge::onMessage, this, 
                      std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    }

private:
    void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp) {
        std::string msg = buf->retrieveAllAsString();
        // 推送到消息队列
        mq_.push(msg);
    }

    void processFromQueue() {
        while (!mq_.empty()) {
            std::string msg = mq_.pop();
            // 处理消息
        }
    }

    TcpServer* server_;
    MessageQueue mq_;
};

相关推荐
青瓦梦滋3 小时前
传输层UDP/TCP协议
linux·网络·c++·网络协议·tcp/ip·udp
寒草3 小时前
【寒草呈献】当巴菲特走进 AI 投研助手
人工智能·架构
ltl3 小时前
推理服务化:Triton、Ray Serve、KServe 与 PD 分离
架构
@insist1233 小时前
系统集成项目管理工程师-安全架构与云原生架构
云原生·架构·软考·安全架构·系统集成项目管理工程师·软考中项·软件水平考试
一只旭宝3 小时前
细讲C加加【9】C++ std::function与std::bind详解|仿函数、绑定器、类成员绑定、占位符、成员偏移指针
开发语言·c++·算法
ltqvibe5 小时前
企业数智化中台的五层架构——AI框架为什么需要纵向贯通
大数据·人工智能·架构
Lhan.zzZ6 小时前
在 Visual Studio 2022 中打造可扩展的动态链接库模块:从零搭建到原理解析
开发语言·c++·visual studio
物质波波波7 小时前
WS-RPE:面向边缘物理AI实时特征值计算的硬件工作窃取调度器与冗余PE激活架构
人工智能·fpga开发·架构·系统架构·硬件架构
zh路西法7 小时前
【3D SLAM源码解读系列】(二)Small_gicp——5 个积木搭出最优点云配准
c++·pcl·icp·fastgicp·smallgicp·gicp
敲代码的玉米C8 小时前
测试一直在写你的真实数据根
前端·人工智能·架构