若依消息中心改造:从单一站内信到多渠道集成

1. 项目背景与需求分析

若依(RuoYi)作为国内广泛使用的开源后台管理系统,其消息通知模块SysNotice在长期使用中暴露出几个典型问题:首先是功能单一,仅支持站内信形式的简单通知;其次是扩展性差,无法对接多种消息渠道;最后是缺乏统一管理界面,导致消息追踪和统计困难。

在实际企业应用中,消息中心需要承担更复杂的职责:

  • 多渠道集成(邮件、短信、企业微信、钉钉等)
  • 消息模板管理
  • 发送记录审计
  • 失败重试机制
  • 用户订阅配置

2. 架构设计方案

2.1 核心模块划分

消息中心 ├── 消息网关(Message Gateway) ├── 模板管理(Template Manager) ├── 发送引擎(Delivery Engine) ├── 记录存储(Record Storage) └── 管理界面(Admin Console)

2.2 技术选型考量

  1. Spring Cloud Stream:解决不同消息中间件的适配问题
  2. Redis Stream:实现消息发送的削峰填谷
  3. MyBatis-Plus:增强原有ORM层的灵活性
  4. Vue3 + TypeScript:重构管理前端

关键决策:保留SysNotice表结构但修改用途,仅作为站内信专用存储,避免影响历史数据

3. 核心实现细节

3.1 消息协议标准化

public class UnifiedMessage { private String messageId; // 雪花算法生成 private MessageType type; // 枚举:NOTICE/ALERT/REMINDER private String templateCode; private Map<String, Object> params; private List<Receiver> receivers; private SendConfig config; // 包含重试策略等 }

3.2 发送流程优化

  1. 接收请求时先持久化到MySQL(保证不丢失)
  2. 通过Redis Stream异步处理
  3. 采用责任链模式处理不同渠道发送
graph TD A[接收请求] --> B[参数校验] B --> C[持久化记录] C --> D[推送到Redis Stream] D --> E[消费者处理] E --> F{渠道判断} F -->|邮件| G[SMTP发送] F -->|短信| H[对接云厂商API]

3.3 失败处理机制

实现要点:

  • 自动重试3次(可配置)
  • 失败消息进入死信队列
  • 提供手动重试接口
  • 记录详细错误日志

4. 关键问题解决方案

4.1 性能优化

  1. 二级缓存设计:
    • 本地缓存(Caffeine):存储模板内容
    • Redis缓存:存储用户订阅配置
  2. 批量发送支持:单次API调用支持最多1000个接收人

4.2 权限控制

改造方案:

@PreAuthorize("@ss.hasMsgPerm('send:email')") public Result sendEmailMessage(...) { // 方法实现 }

4.3 历史数据迁移

编写Flyway迁移脚本:

-- V2__convert_notice.sql ALTER TABLE sys_notice ADD COLUMN msg_type VARCHAR(20); UPDATE sys_notice SET msg_type = 'LEGACY';

5. 前端改造要点

5.1 管理界面增强

  1. 新增消息看板:展示实时发送统计
  2. 模板编辑器:支持变量插值语法
  3. 发送记录查询:支持多条件筛选

5.2 用户端改进

  1. 消息分类展示(重要/普通)
  2. 多终端已读状态同步
  3. 订阅偏好设置

6. 部署注意事项

  1. Redis配置要求:
spring: redis: stream: poll-timeout: 5000 consumer-group: msg-center-group
  1. Nacos新增配置:
# 邮件发送线程池配置 msg.email.pool.core-size=5 msg.email.pool.max-size=20
  1. 健康检查端点:
@GetMapping("/health") public MessageCenterHealth checkHealth() { // 检查各渠道连接状态 }

7. 实测性能对比

测试环境:4C8G服务器,MySQL 8.0,Redis 6.2

场景原SysNotice新消息中心提升
单条发送延迟120ms80ms33%
批量发送(100条)2.1s0.8s62%
高并发(1000QPS)失败率12%失败率0.3%-

8. 扩展设计建议

  1. 插件化架构:通过SPI机制支持第三方渠道接入
public interface MessageChannel { String getChannelType(); SendResult send(UnifiedMessage message); }
  1. 流量控制:基于Sentinel实现:
  • 按照消息类型限流
  • 按照发送方限流
  1. 消息追踪:集成SkyWalking实现全链路追踪

9. 典型问题排查记录

  1. 消息重复消费问题
  • 现象:相同消息ID被处理多次
  • 原因:消费者组配置错误
  • 解决:确保每个服务实例有独立consumerGroup
  1. 模板渲染性能差
  • 现象:高并发下模板解析耗时增加
  • 优化:引入预编译机制
Template template = TemplateCache.get(templateCode); if(template == null) { template = compileTemplate(templateText); TemplateCache.put(templateCode, template); }
  1. 企业微信回调失败
  • 现象:回调URL返回403
  • 排查:网关白名单未配置
  • 解决:在网关模块添加路径放行规则

改造过程中发现,原有消息表的create_time字段精度只到秒级,建议统一修改为DATETIME(3)存储毫秒时间戳,方便后续问题排查时精确追踪消息流转过程。