系统架构设计文档
总体架构
┌─────────────────────────────────────────────────────────────────────────┐
│ 客户端层 (Client Layer) │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ 访客端 SDK │ │ 客服管理后台 │ │ 官网/第三方应用 │ │
│ │ (嵌入式) │ │ (Vue3) │ │ (集成点) │ │
│ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │
│ │ │ │ │
│ └────────────────────┬───┴────────────────────────┘ │
│ │ │
└────────────────────────────────┼─────────────────────────────────────────┘
│
┌────────────┴────────────┐
│ WebSocket / HTTP │
│ 长连接 + REST API │
└────────────┬────────────┘
│
┌────────────────────────────────┼─────────────────────────────────────────┐
│ 应用层 (Application Layer) │
├────────────────────────────────┼─────────────────────────────────────────┤
│ │ │
│ ┌─────────────────────────────▼──────────────────────────────────────┐ │
│ │ Spring Boot 应用 │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │
│ │ │ REST API │ │ Netty │ │ 自定义业务逻辑 │ │ │
│ │ │ (Controller) │ │ WebSocket │ │ (Handler/Manager) │ │ │
│ │ └──────────────┘ │ Handler │ └──────────────────────┘ │ │
│ │ └──────────────┘ │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │
│ │ │ 认证授权 │ │ 聊天核心 │ │ 数据统计分析 │ │ │
│ │ │ (Security) │ │ (ChatService)│ │ (Statistics) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────────┘ │ │
│ │ │ │
│ └────────────────────────────────┬───────────────────────────────────┘ │
│ │ │
│ ┌──────────────┴──────────────┐ │
│ │ 事务 + ORM 映射层 │ │
│ │ (MyBatis Plus) │ │
│ └──────────────┬──────────────┘ │
│ │ │
└───────────────────────────────────┼──────────────────────────────────────┘
│
┌───────────────┴───────────────┐
│ 数据持久化层 │
└───────────────┬───────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ MySQL │ │ Redis │ │ Aliyun OSS │
│ 8.0+ │ │ 6.0+ │ │ (文件存储) │
│ │ │ │ │ │
│ • 会话数据 │ │ • 在线状态 │ │ • 文件永久存储 │
│ • 消息记录 │ │ • 排队队列 │ │ • 图片/视频 │
│ • 访客信息 │ │ • 离线消息 │ └──────────────┘
│ • 统计数据 │ │ • 计数器 │
└──────────────┘ │ • 缓存 │
└──────────────┘
分层架构详解
1. 表现层 (Presentation Layer)
前端应用
客户端
├── 访客端 SDK (嵌入式聊天窗口)
│ ├── WebSocket 连接
│ ├── 消息收发
│ ├── 离线处理
│ └── 事件通知
│
├── 客服后台 (Vue3 + Element Plus)
│ ├── 客服工作台
│ ├── 访客管理
│ ├── 数据统计
│ ├── 系统配置
│ └── 权限管理
│
└── 集成接口
├── 全局 API 调用
├── 事件监听
└── 回调处理
2. 应用层 (Application Layer)
核心模块
Spring Boot 应用
│
├── HTTP API 端点 (REST Controller)
│ ├── /im/visitor/* (访客接口)
│ ├── /im/cs/* (客服接口)
│ ├── /im/statistics/* (统计接口)
│ ├── /im/admin/* (管理接口)
│ └── /im/system/* (系统接口)
│
├── WebSocket 处理器 (Netty)
│ ├── 认证握手处理
│ ├── 消息路由处理
│ ├── 会话管理处理
│ ├── 心跳检测处理
│ └── 连接状态处理
│
├── 业务服务层 (Service)
│ ├── 聊天服务 (ChatService)
│ │ ├── 消息发送
│ │ ├── 消息保存
│ │ └── 消息转发
│ │
│ ├── 会话服务 (SessionService)
│ │ ├── 会话创建
│ │ ├── 会话结束
│ │ ├── 会话查询
│ │ └── 会话转移
│ │
│ ├── 客服服务 (CsService)
│ │ ├── 上线/离线
│ │ ├── 状态管理
│ │ ├── 接待分配
│ │ └── 转接处理
│ │
│ ├── 访客服务 (VisitorService)
│ │ ├── 访客创建
│ │ ├── 信息更新
│ │ ├── 状态维护
│ │ └── 历史查询
│ │
│ ├── 排队服务 (QueueService)
│ │ ├── 入队处理
│ │ ├── 出队分配
│ │ └── 位置查询
│ │
│ ├── 统计服务 (StatisticsService)
│ │ ├── 实时统计
│ │ ├── 历史统计
│ │ ├── 报表生成
│ │ └── 数据分析
│ │
│ └── 认证服务 (AuthService)
│ ├── 登录认证
│ ├── Token 管理
│ ├── 权限检查
│ └── 会话管理
│
└── 通用工具层
├── Redis 工具
├── JWT 工具
├── 密码工具
├── 异常处理
└── 日志管理
3. 数据层 (Data Access Layer)
ORM 映射
MyBatis Plus
├── Visitor Mapper (访客数据访问)
├── ChatSession Mapper (会话数据访问)
├── ChatMessage Mapper (消息数据访问)
├── Account Mapper (账户数据访问)
├── Role Mapper (角色数据访问)
├── Permission Mapper (权限数据访问)
└── Statistics Mapper (统计数据访问)
数据库设计
MySQL 8.0
├── 核心表
│ ├── visitor (访客表)
│ ├── chat_session (聊天会话表)
│ ├── chat_message (聊天消息表)
│ ├── account (账户表)
│ ├── role (角色表)
│ ├── permission (权限表)
│ └── im_company (企业表)
│
└── 支持表
├── quick_reply (快速回复)
├── keyword_reply (关键词回复)
├── sensitive_word (敏感词)
└── audit_log (审计日志)
缓存策略
Redis 6.0+
├── 在线状态 (Hash)
│ └── im:online:cs (在线客服状态)
│
├── 排队队列 (Sorted Set)
│ └── im:queue:visitor (访客排队队列)
│
├── 消息缓存 (List/Hash)
│ ├── im:offline:msg:* (离线消息)
│ └── im:queue:msg:* (排队消息)
│
├── 计数器 (String)
│ ├── im:counter:online_visitor (在线访客计数)
│ ├── im:counter:online_cs (在线客服计数)
│ ├── im:counter:active_session (活跃会话计数)
│ └── im:counter:waiting_queue (排队人数)
│
└── 通道映射 (Hash)
├── im:channel:visitor (访客通道映射)
└── im:channel:cs (客服通道映射)
核心数据流
1. 访客发送消息流程
访客端 SDK
│
├─ 用户输入消息
│
▼
WebSocket 连接
│
├─ 序列化消息 (JSON)
│
▼
Netty Server (8088)
│
├─ 接收消息
│
▼
ImMessageHandler
│
├─ 解析消息类型
│
▼
ChatHandler
│
├─ 校验消息
│ └─ 检查会话状态
│ └─ 检查内容合法性
│
▼
判断客服分配状态
│
├─ 已分配 → 转发给客服 + 保存 DB + 标记已读
│
├─ 未分配 → 加入排队 + 保存排队消息
│
└─ 客服离线 → 保存为离线消息
│
▼
异步持久化
│
└─ MySQL: 保存消息记录
Redis: 缓存最近消息
2. 客服上线流程
客服登录
│
├─ 输入账号密码
│
▼
HTTP 请求到 /im/cs/login
│
├─ 认证用户
│ └─ 校验密码
│ └─ 生成 JWT Token
│
▼
WebSocket 连接 (8088)
│
├─ 发送 HandShake 消息
│
▼
认证握手处理
│
├─ 验证 JWT Token
│ └─ 解析客服 ID
│ └─ 检查权限
│
▼
客服上线
│
├─ 从数据库恢复接待数
│ └─ 查询活跃会话
│
├─ Redis 记录在线状态
│ └─ im:online:cs 添加客服
│ └─ 增加在线客服计数
│
▼
分配排队访客
│
├─ 检查排队队列
│ └─ im:queue:visitor 取出访客
│
├─ 分配客服
│ └─ 创建会话
│ └─ 增加接待数
│
├─ 推送离线消息
│ └─ 从 Redis 取离线消息
│ └─ 发送给客服
│
└─ 通知访客
└─ 发送 csAssigned 消息
3. 智能排队算法
访客进入排队
│
▼
检查客服状态
│
├─ 有可用客服 → 立即分配
│ │
│ ├─ 选择接待数最少的客服
│ ├─ 优先选择上线时间最早的
│ └─ 企业隔离处理
│
└─ 无可用客服 → 加入排队队列
│
├─ 存储到 Redis (Sorted Set)
│ └─ 按时间戳排序 (FIFO)
│
└─ 保存排队消息
└─ im:queue:msg:{visitorId}
4. 离线消息处理
访客断开连接
│
▼
记录断开时间戳
│
├─ 60 秒保护期
│ └─ im:visitor:disconnect:{visitorId}
│
▼
客服发送消息
│
├─ 检查访客在线状态
│
├─ 离线 → 保存为离线消息
│ └─ im:offline:msg:{visitorId}
│ └─ TTL: 24 小时
│
└─ 标记待推送
│
▼
访客重新连接
│
├─ 在保护期内 → 复用会话
│ └─ 恢复消息收取位置
│ └─ 推送离线消息
│
└─ 超过保护期 → 创建新会话
└─ 作为新访客处理
模块关系图
模块依赖关系
┌────────────────────────────────────────────────────────────────┐
│ im-parent (父工程) │
├────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ im-deploy (启动模块) │ │
│ │ 主程序入口: ImApplication │ │
│ └───────────────┬────────────────────────────────────────┘ │
│ │ 依赖 │
│ ┌──────────────▼──────────────────────────────────────────┐ │
│ │ im-server (微服务集合) │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ im-chat (聊天核心模块) ⭐ │ │ │
│ │ │ ├── Netty WebSocket Handler │ │ │
│ │ │ ├── ChatHandler / SessionHandler │ │ │
│ │ │ ├── CsManager / SessionManager │ │ │
│ │ │ ├── ChatMessageService │ │ │
│ │ │ ├── StatisticsService │ │ │
│ │ │ └── VisitorService │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ │ ↑ 依赖 │ │
│ │ ┌────────────┬───────┴──────┬──────────┬────────────┐ │ │
│ │ │ │ │ │ │ │ │
│ │ │ im-auth │ im-model │ im-oss │ im-common │ │ │
│ │ │ 认证授权 │ 数据模型 │ 文件存储 │ 通用工具 │ │ │
│ │ └────────────┴──────────────┴──────────┴────────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────┘
im-common 通用模块
im-common
├── Redis 工具 (RedisUtils)
│ ├── 基本操作 (get/put/del)
│ ├── Hash 操作 (hGet/hPut)
│ ├── Sorted Set (zAdd/zRank)
│ └── 原子操作 (incr/decr)
│
├── JWT 工具 (JwtUtils)
│ ├── Token 生成
│ ├── Token 解析
│ └── 过期校验
│
├── 异常处理
│ ├── GlobalExceptionHandler
│ ├── BusinessException
│ └── 全局错误码
│
├── 结果封装
│ ├── Result<T>
│ └── PageResult<T>
│
└── 其他工具
├── PasswordUtils (密码加密)
├── SecurityUtils (获取当前用户)
├── RegionUtils (IP 地址解析)
└── CodeUtils (验证码生成)
并发处理与同步机制
多线程架构
Spring Boot 应用
│
├── Netty EventLoop (IO 线程池)
│ ├── Handler 处理 (非阻塞)
│ ├── 消息路由 (高效)
│ └── 连接管理 (轻量)
│
├── Spring 线程池
│ ├── @Async 异步任务
│ │ ├── 消息持久化
│ │ ├── 统计计算
│ │ └── 邮件通知
│ │
│ └── 定时任务
│ ├── 心跳检测
│ ├── 离线消息清理
│ └── 数据统计汇总
│
└── 数据库连接池 (HikariCP)
├── 最大连接数: 20
├── 最小空闲: 5
└── 超时时间: 30s
状态同步
Redis 作为单一事实源
│
├── 在线状态同步
│ ├── 客服上线 → Redis 记录
│ ├── 客服离线 → Redis 删除
│ ├── 接待数变化 → Redis 更新
│ └── 状态查询 → 优先读 Redis
│
├── 排队队列同步
│ ├── 访客入队 → Redis ZADD
│ ├── 分配出队 → Redis ZREM
│ └── 位置查询 → Redis ZRANK
│
└── 计数器同步
├── 原子操作 (INCR/DECR)
├── 避免竞态条件
└── 定期校对 DB
性能优化策略
缓存层次
内存读写速度: 纳秒级
↑
│ (100x)
Redis 缓存: 微秒级
↑
│ (100x)
MySQL 数据库: 毫秒级
↑
│ (100x)
磁盘 IO: 秒级
优化实践
-
数据库查询优化
- 索引设计 (session_id, visitor_id, cs_id)
- 批量操作 (减少 IO 次数)
- 连接池管理 (避免连接泄漏)
-
缓存策略
- 热数据优先 (在线状态、排队队列)
- TTL 设置 (避免内存泄漏)
- 缓存预热 (应用启动时)
-
消息队列
- 异步持久化
- 批量写入 DB
- 削峰填谷
-
连接管理
- WebSocket 长连接复用
- 心跳保活 (30s)
- 优雅关闭处理
高可用架构设计
单机架构 (开发环境)
┌─────────────────┐
│ Spring Boot │
│ 应用 (8080) │
├─────────────────┤
│ Netty (8088) │
│ WebSocket │
└────────┬────────┘
│
┌────┴──────┐
▼ ▼
MySQL Redis
集群架构 (生产环境)
┌──────────────────────────────────┐
│ Nginx (负载均衡) │
│ - 轮询分发 │
│ - WebSocket 支持 │
└──────────────┬───────────────────┘
│
┌──────────┼──────────┐
│ │ │
▼ ▼ ▼
实例1 实例2 实例3
(8080) (8080) (8080)
│ │ │
└──────────┼──────────┘
│
┌──────────┴──────────┐
▼ ▼
MySQL Cluster Redis Cluster
(读写分离) (集群模式)
安全架构
认证流程
用户登录
│
├─ 输入用户名/密码
│
▼
HTTP POST /login
│
├─ 校验用户名密码
│
├─ 查询数据库
│
├─ 密码比对 (BCrypt)
│
▼
生成 JWT Token
│
├─ 包含用户信息
│ ├─ userId
│ ├─ role
│ └─ permissions
│
├─ 设置过期时间 (12 小时)
│
▼
返回 Token 给客户端
│
├─ 存储在本地存储
│
▼
后续请求携带 Token
│
├─ Header: Authorization: Bearer {token}
│
▼
JWT 过滤器验证
│
├─ 解析 Token
│ ├─ 验证签名
│ ├─ 检查过期时间
│ └─ 获取用户信息
│
▼
权限检查
│
├─ @RequirePermission 注解
│ └─ 检查用户权限
│
▼
允许/拒绝请求
权限模型
RBAC (Role-Based Access Control)
│
├── 用户 (User)
│ └─ 多个角色
│
├── 角色 (Role)
│ ├─ 超级管理员
│ ├─ 企业管理员
│ ├─ 客服
│ └─ 访客
│
└── 权限 (Permission)
├─ 账户管理
├─ 客服管理
├─ 访客管理
├─ 数据统计
└─ 系统设置
总结
关键技术选型
| 层级 | 技术 | 优势 | 用途 |
|---|---|---|---|
| 应用层 | Spring Boot 3.2 | 快速开发、生态完善 | 主框架 |
| 通信层 | Netty 4.1 | 高性能、异步 | WebSocket |
| 数据库 | MySQL 8.0 | 可靠性、ACID | 数据持久化 |
| 缓存 | Redis 6.0 | 极速访问、多数据结构 | 状态/计数/队列 |
| ORM | MyBatis Plus | 灵活、强大 | 数据访问 |
| 安全 | Spring Security + JWT | 标准、可靠 | 认证授权 |
| 前端 | Vue3 + Vite | 快速、现代 | 客服后台 |
架构特点
✅ 高性能 - Netty 异步、Redis 缓存、数据库优化
✅ 高可用 - 支持集群、故障转移、消息持久化
✅ 易扩展 - 模块化设计、服务解耦
✅ 易维护 - 清晰分层、代码规范
✅ 安全可靠 - 权限控制、加密存储、审计日志