基于 muduo + MySQL + Redis 的分布式聊天服务器,支持注册登录、好友管理、单聊、群聊、离线消息、跨节点消息转发和 Nginx TCP 负载均衡。
- 基于 muduo 多 Reactor 模型实现 TCP 长连接通信
- 基于 JSON 设计应用层消息协议,支持注册、登录、单聊、群聊等业务消息
- 基于 MySQL / MariaDB 持久化用户、好友、群组和离线消息
- 基于 Redis Pub/Sub 实现多 ChatServer 节点之间的消息转发
- 支持 Nginx Stream 对多个 ChatServer 节点进行 TCP 四层负载均衡
- 引入 message_id、ACK 和消息状态字段,用于消息投递跟踪和未读消息同步
- 支持心跳保活,降低长连接空闲断开的概率
用户登录到某个 ChatServer 后,该节点维护 userid -> TcpConnection 的本地连接映射,并订阅 Redis 中以 userid 命名的 channel。
当用户 A 向用户 B 发送消息时:
- 如果 B 在线且连接在本节点,直接通过本地 TcpConnection 投递。
- 如果 B 在线但连接在其他节点,通过 Redis Pub/Sub 转发到对应 ChatServer。
- 如果 B 离线,消息持久化到数据库,等待 B 下次登录后同步。
.
├── benchmark/ # 基础测试脚本
├── bin/ # 编译生成的可执行文件
├── config/ # 服务端环境变量和 Nginx 配置示例
├── docs/ # 架构、协议和测试说明
├── include/ # 头文件
├── scripts/ # 编译和启动脚本
├── sql/ # 数据库初始化脚本
├── src/
│ ├── client/ # 客户端代码
│ └── server/
│ ├── db/ # MySQL 连接封装
│ ├── model/ # 用户、好友、群组、消息模型
│ ├── redis/ # Redis 发布订阅封装
│ ├── chatserver.cpp # muduo TcpServer 封装
│ └── chatservice.cpp # 业务分发与核心逻辑
├── thirdparty/ # 第三方头文件
└── CMakeLists.txt
开发和测试环境:
Alibaba Cloud Linux 3 / CentOS-like
C++11
CMake
muduo
MySQL / MariaDB
Redis
hiredis
Nginx
nlohmann/json
安装基础依赖:
yum install -y gcc gcc-c++ cmake make mysql-devel hiredis-devel nginx redis mariadb-servermuduo 需要单独安装,并确保系统可以链接:
muduo_net
muduo_base
systemctl enable --now mariadb
systemctl enable --now redis
redis-cli pingRedis 正常时应返回:
PONG
mysql -uroot -p < sql/init.sql如果本地 root 用户无密码:
mysql -uroot < sql/init.sqlcp config/server.env.example config/server.env
vim config/server.env
source config/server.env示例配置:
CHAT_DB_HOST=127.0.0.1
CHAT_DB_PORT=3306
CHAT_DB_USER=root
CHAT_DB_PASSWORD=123456
CHAT_DB_NAME=chat
CHAT_REDIS_HOST=127.0.0.1
CHAT_REDIS_PORT=6379
CHAT_REDIS_PASSWORD=
CHAT_REDIS_DB=0./scripts/build.sh编译完成后会生成:
bin/ChatServer
bin/ChatClient
source config/server.env
./bin/ChatServer 127.0.0.1 6000新开终端启动客户端:
./bin/ChatClient 127.0.0.1 6000客户端支持注册、登录、添加好友、单聊、创建群组、加入群组和群聊。
启动两个 ChatServer 节点:
source config/server.env
./bin/ChatServer 127.0.0.1 6000source config/server.env
./bin/ChatServer 127.0.0.1 6002将 config/nginx_tcp.conf 合并到 Nginx 配置后,检查并重载:
nginx -t
nginx -s reload客户端连接 Nginx 入口:
./bin/ChatClient 127.0.0.1 8000Nginx 负责将不同客户端连接分发到多个 ChatServer 节点,Redis Pub/Sub 负责不同节点之间的消息转发。
chat_message 表用于记录消息投递状态:
0 created 服务端已持久化,尚未投递到接收方连接
1 delivered 服务端已投递到接收方连接,等待客户端 ACK
2 acked 客户端已确认收到
基本流程:
1. 服务端收到聊天请求后生成 message_id
2. 消息写入 chat_message 表,状态为 created
3. 接收方在线时立即投递,并更新为 delivered
4. 客户端收到消息后发送 ACK
5. 服务端收到 ACK 后将状态更新为 acked
6. 接收方离线时,消息保留在数据库中
7. 接收方重新登录后,服务端同步未确认消息
项目提供 benchmark/bench_client.py,用于模拟多客户端连接、登录和单聊消息收发,主要用于功能验证和稳定性观察。
注册测试用户:
python3 benchmark/bench_client.py \
--host 127.0.0.1 \
--port 6000 \
--mode register \
--users 100 \
--password 123456 \
--concurrency 50单聊链路测试:
python3 benchmark/bench_client.py \
--host 127.0.0.1 \
--port 6000 \
--mode chat \
--start-id 1 \
--users 100 \
--password 123456 \
--messages-per-user 20 \
--concurrency 50该脚本用于辅助验证连接、登录、消息收发和 ACK 流程,不作为极限性能测试结果。
- 将当前
JSON + '\n'协议升级为固定长度消息头 + JSON Body - 优化客户端输入校验,避免非法输入导致客户端异常
- 优化可靠消息投递链路,支持 ACK 批量更新和异常重试
- 增加 CI 构建检查,保证代码提交后能够自动编译验证
