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_;
};

相关推荐
一只川页几秒前
从“对话”到“实干”:大模型应用架构演进全景解析
人工智能·架构
..过云雨7 分钟前
【负载均衡oj项目】01. 项目概述及准备工作
linux·c++·html·json·负载均衡
yuuki23323311 分钟前
【C++ 智能指针全解析】从内存泄漏痛点到 RAII + unique/shared/weak_ptr 手撕实现
开发语言·c++
金智维科技官方15 分钟前
Agent架构综述:从Prompt到Context
java·微服务·架构·agent
毛骗导演20 分钟前
万字解析 OpenClaw 源码架构-跨平台应用之Android 应用
android·前端·架构
闻缺陷则喜何志丹23 分钟前
【构造 前缀和】P8902 [USACO22DEC] Range Reconstruction S|普及+
c++·算法·前缀和·洛谷·构造
深圳市雷龙发展有限公司longsto39 分钟前
在Memory持续上涨的周期里,北京君正内置DDR主控的架构价值
架构
老四啊laosi44 分钟前
[C++进阶] 16. 继承
c++·继承
翻斗包菜1 小时前
LNMP/LNAMP 架构部署实战:从环境搭建到 Discuz 部署 + 动静分离实现
架构
Moe4881 小时前
基于 AOP 与 Redisson 的分布式锁实现:自动加锁、解锁与 SpEL 参数解析
java·后端·架构