一个企业级实时客服聊天系统 IM-Parent
本文介绍了一个从零开发的完整开源项目:IM-Parent。一个高性能、功能完整的企业级实时聊天系统,采用 Spring Boot + Netty + Vue3 技术栈。
前言
做开发这么多年,最大的遗憾就是没有开源过一个像样的项目。最近完成了一个完整的实时聊天系统,决定将其开源,分享给社区。这篇文章将详细介绍这个项目的核心设计、技术方案、以及开发过程中的一些经验。
项目介绍
IM-Parent 是一个企业级实时聊天系统,提供完整的访客与客服实时交互、智能排队、消息持久化、数据统计等功能。
核心特性
- ✨ 实时通信 - 基于 WebSocket 和 Netty 的低延迟双向通信
- 👥 客服管理 - 支持多客服在线、自动分配、智能转接
- 💬 消息管理 - 完整的消息持久化、离线消息推送、聊天记录查询
- 📊 智能排队 - 访客自动排队,客服有空位时自动分配
- 📈 数据统计 - 访客来源、地域分布、对话时长等多维度分析
- 🔄 重连保护 - 网络波动时自动重连,保持会话状态
- 🏢 多租户 - 企业隔离,支持 SaaS 部署
部分截图
访客端演示


客服工作台



在线体验地址:
请勿随意删除体验账号中的系统配置数据,谢谢 ,目前代码仓库和文档等部署还没有写好,如有需要可直接留言给我发送代码
技术栈
后端技术
┌─────────────────────────────────────┐
│ Spring Boot 3.2 应用层 │
│ ├── REST API (Controller) │
│ ├── 业务逻辑 (Service) │
│ └── 数据访问 (Mapper/ORM) │
└─────────────────────────────────────┘
↑ ↑
┌────┴────┐ ┌────┴─────┐
│ Netty │ │ MyBatis │
│WebSocket│ │ Plus │
└────┬────┘ └────┬─────┘
│ │
[WebSocket] [MySQL 8.0]
[8088 Port]
客户端(访客)
↓ WebSocket
┌─────────────────────────────────┐
│ Netty WebSocket Server │
│ ├─ 认证握手 Handler │
│ ├─ 消息处理 Handler │
│ ├─ 会话管理 Handler │
│ └─ 心跳检测 Handler │
└────────┬────────────────────────┘
│
┌────┴─────────┬────────────┐
↓ ↓ ↓
[MySQL] [Redis] [OSS]
[会话数据] [在线状态] [文件]
核心模块
- im-common (通用模块)
工具类库
├── Redis 工具 (RedisUtils)
├── JWT 工具 (JwtUtils)
├── 密码工具 (PasswordUtils)
├── IP 解析工具 (RegionUtils)
└── 异常处理 (GlobalExceptionHandler)
2. im-auth (认证授权)
身份认证与权限管理
├── 账户管理 (多角色)
├── JWT 认证
├── 权限控制 (@RequirePermission)
└── CORS 配置
3. im-chat (聊天核心) ⭐
实时聊天引擎
├── Netty WebSocket Handler
├── 消息路由 (ChatHandler)
├── 会话管理 (SessionManager)
├── 客服管理 (CsManager)
├── 排队管理 (QueueManager)
└── 统计分析 (StatisticsService)
- im-model (数据模型)
数据定义
├── POJO (访客/会话/消息)
└── 常量定义 (ImConstant)
5. im-oss (文件存储)
文件上传
└── 阿里云 OSS 集成
核心技术
- Java 17 - 最新的 LTS 版本,支持虚拟线程(未来优化方向)
- Spring Boot 3.2 - 最新稳定版,轻量级快速开发
- Netty 4.1 - 高性能网络框架,支持 WebSocket
- MyBatis Plus - ORM 框架,简化数据库操作
- Spring Security - 安全框架,支持 JWT 认证
- Redis 6.0+ - 缓存和计数器存储
前端技术
- Vue 3 - 渐进式框架
- Vite - 快速开发和构建
- Element Plus - 企业级 UI 组件库
- WebSocket - 实时通信
核心设计亮点
1. 实时通信方案
消息流转:
访客消息
↓
ChatHandler.handleVisitorMessage()
↓
判断客服分配状态
├─ 已分配 → 转发给客服 + 保存数据库
├─ 未分配 → 加入排队队列/保存排队消息
└─ 客服离线 → 保存为离线消息
↓
客服上线时推送离线消息
重连保护机制:
访客断开连接
↓
记录断开时间戳到 Redis (60s 保护期)
↓
访客重新连接
├─ 在保护期内 → 复用会话,推送离线消息
└─ 超过保护期 → 创建新会话
2. 智能排队算法
分配策略:
客服登录
↓
从数据库恢复接待数
↓
获取排队中的访客
↓
循环分配(检查客服容量)
├─ 客服有空位 → 分配访客,发送通知
├─ 客服已满 → 继续排队
└─ 无客服在线 → 保存为排队消息
负载均衡:
选择最优客服
├─ 优先级 1: 接待数最少
├─ 优先级 2: 上线时间最早
└─ 优先级 3: 相同企业隔离
3. 计数器管理 (性能关键)
计数项:
online_visitor- 在线访客总数active_session- 活跃会话数online_cs- 在线客服数waiting_queue- 排队访客数
修复的 Bug:
在开发过程中发现了一个关键的计数不准确问题:
原始问题:
访客重连时
↓
新连接建立 → 旧连接异步关闭
↓
计数增加 / 计数减少顺序错乱
↓
导致计数偏高
解决方案:
在新连接绑定时
├─ 检测是否有旧连接
├─ 旧连接关闭时同步减少计数
└─ 新连接建立时增加计数
↓
保证计数准确性
4. 数据持久化策略
消息存储:
实时消息
↓
异步保存到 MySQL (批量写入)
↓
同时保存到 Redis (临时缓存)
↓
定期清理过期消息
离线消息:
访客离线
↓
消息保存到 Redis (24h TTL)
├─ im:offline:msg:{visitorId}
└─ im:queue:msg:{visitorId}
↓
访客上线时推送
↓
标记为已读并持久化
性能指标
实时性
| 指标 | 目标值 | 实际值 | 备注 |
|---|---|---|---|
| 消息延迟 | <100ms | ~50ms | WebSocket 直连 |
| 连接建立 | <500ms | ~200ms | 握手优化 |
| 心跳间隔 | 30s | 30s | 保持活跃 |
| 重连时间 | <3s | ~1s | 自动恢复 |
并发能力
- 单实例连接数: 5000+ (JVM 内存限制)
- 每秒消息吞吐: 10,000+ (取决于数据库)
- 客服接待能力: 每客服 5 人 (可配置)
- 排队处理速度: 秒级分配
资源占用
| 资源 | 配置 | 说明 |
|---|---|---|
| 内存 | 1024MB | Xmx1024m |
| CPU | 2+ cores | 推荐 4 cores |
| 磁盘 | 10GB | 日志 + 数据库 |
| 网络 | 100Mbps+ | 推荐千兆 |
开源规划
已完成
✅ 核心功能完成
✅ 完整文档编写
✅ Docker 部署支持
✅ MIT 许可证发布
✅ 开源文档体系
近期计划
🔲 AI 机器人集成 (OpenAI/通义千问)
🔲 工单系统模块
🔲 知识库与常见问题
🔲 性能监控面板
🔲 多语言支持
技术细节深度讨论
为什么选择 Netty?
[Netty vs 其他框架对比图]
- 高性能: 基于 NIO,支持百万级连接
- 异步通信: 事件驱动模型
- WebSocket 支持: 天然支持 WebSocket 协议
- 成熟稳定: 广泛应用于生产环境
Spring WebSocket
↓
Netty (底层实现)
↓
NIO (非阻塞 I/O)
↓
性能优势: 高并发, 低延迟
为什么选择 Redis?
- 高速缓存: 在线状态, 排队队列
- 计数器: 访客/会话计数
- 分布式支持: 支持集群扩展
- 持久化: RDB/AOF 保证数据安全
如何处理并发冲突?
乐观锁 vs 悲观锁:
选择乐观锁原因:
├─ 并发冲突概率低 (访客消息顺序发送)
├─ 性能优势明显
└─ 重试机制简单
Redis 实现:
INCR/DECR 原子操作
↓
确保计数器准确性
常见问题解答
Q1: 单机能支持多少并发?
A: 根据 JVM 配置,单机约 5000 个并发连接。通过水平扩展 + 负载均衡可突破限制。
[并发扩展图:请插入单机到集群的扩展架构图]
单机模式 → 5K 并发
集群模式 (3 台) → 15K 并发
负载均衡 → 无限扩展
Q2: 如何保证消息不丢失?
A: 多层保障:
- 实时推送 + 立即持久化
- 访客离线时保存离线消息
- 客服无法接收时保存排队消息
- 定期数据库备份
Q3: 如何进行性能监控?
A: 推荐方案:
应用日志 (Logback)
↓
ELK Stack (Elasticsearch + Logstash + Kibana)
↓
业务指标 (Prometheus)
↓
告警面板 (Grafana)
Q4: 支持 AI 机器人吗?
A: 架构已预留扩展接口。可集成:
- OpenAI GPT
- 阿里通义千问
- 腾讯混元
- 本地 LLaMA
Q5: 如何进行二次开发?
A: 模块化设计,易于扩展:
添加新功能
├─ 新增 Service 实现
├─ 新增 Controller 端点
├─ 新增数据库表
└─ 编写相关测试
开发经验分享
1. 重连保护的重要性
最初设计时没有重连保护,导致频繁断线的访客被当成新用户,造成大量垃圾会话。后来添加了 60 秒保护期,问题彻底解决。
教训: 移动互联网环境中,用户掉线和重连是常态,必须考虑。
2. 计数准确性问题
这是最难调试的 bug。症状是在线访客数经常比实际多。根本原因是旧连接关闭的处理时序问题。
解决过程:
- 第一版:添加重连检查 ❌ (没解决)
- 第二版:在握手时同步处理旧连接 ✅
3. 离线消息的取舍
起初想实现 100% 不丢消息,结果系统变得很复杂。后来简化为:
- 24 小时内的消息必须推送
- 24 小时后的消息可以丢弃
- 用户主动查询可获取历史记录
权衡: 复杂度 vs 业务价值
4. Redis 内存优化
线上某次遇到 Redis 内存溢出,排查发现离线消息没有正确清理。解决方案:
- 每条消息设置 TTL
- 推送成功后立即删除
- 定期清理过期数据
展望与思考
短期目标
- AI 机器人 - 支持客服机器人自动回复
- 工单系统 - 复杂问题升级为工单
- 知识库 - 常见问题自助查询
中期目标
- 多渠道 - 支持微信/钉钉/企业微信接入
- 数据分析 - 深度挖掘对话数据
- 性能优化 - 支持 100K+ 并发
长期目标
- 生态建设 - 完整的开源生态
- 社区驱动 - 核心由社区维护
- 商业化 - 提供云服务版本
为什么我决定开源
- 技术债清零 - 开源倒逼代码质量提升
- 学习机会 - 从 Review 中学习最佳实践
- 社区反馈 - 获得真实用户的需求
- 职业发展 - 建立个人影响力
总结
IM-Parent 是一个完整的、生产级别的开源项目。无论你是想学习企业应用开发,还是想要一个开箱即用的聊天系统,都能从这个项目中获益。
项目特点:
- ✅ 功能完整
- ✅ 文档齐全
- ✅ 代码规范
- ✅ 易于部署
- ✅ 易于扩展
感谢你的阅读!如果这篇文章对你有帮助,欢迎分享、收藏和点赞。
更多推荐



所有评论(0)