网站优化

网站优化

Products

当前位置:首页 > 网站优化 >

如何用📨 Spring Boot 3 集成 MQ 构建聊天消息存储系统?

GG网络技术分享 2026-04-16 04:56 0


前言:别让聊天系统像老牛车一样慢

说实话, 很多小伙伴在写即时聊天功能时总是忍不住把数据库写入消息推送绑在一起——后来啊就是用户点了“发送”,页面卡到转圈儿,甚至服务器直接抛异常。这不就是把一条信息塞进了拥堵的高速路,却忘了给它加个快递通道吗呃?

没耳听。 于是 我决定把 Spring Boot 3 与各种MQ玩个大杂烩,让聊天消息先飞到队列里再让后端慢慢地、稳稳地写进数据库。下面这篇“烂文”会把整个过程拆得稀巴烂,还顺手塞进几段乱七八糟的代码、表格和情绪。

📨 Spring Boot 3 整合 MQ 构建聊天消息存储系统

1️⃣ 为何要引入 MQ?

解耦合——把「用户发送」和「消息持久化」分成两条平行线; 削峰填谷——高峰期来一堆消息, 队列里先排队,消费端慢慢吃; 容错弹性——即使数据库短暂挂掉,消息也不会丢,只会在队列里等,走捷径。。

2️⃣ 选型大比拼

中低200k+基于分区日志 大数据实时分析
消息队列 部署难度 吞吐量 持久化特性 适合场景
RabbitMQ中等10k~50k可靠持久化 + ACK 机制聊天、 订单、日志收集
ActiveMQ 5k~20k事务+持久化可选企业内部系统集成
RocketMQ 100k+强一致性日志存储 金融、海量流式数据
Kafka

3️⃣ 环境准备:Docker + Spring Boot 3 + JDK 17 🎉

先拉一个带管理插件的 RabbitMQ 镜像:,蚌埠住了!

docker pull rabbitmq:4.1-management
docker run --name rabbitmq \
    -p 5672:5672 -p 15672:15672 \
    --restart always -d rabbitmq:4.1-management
# 注意:这里端口映射随意改,别跟本地 MySQL 冲突

Spring Boot 项目里加上依赖:


    org.springframework.boot
    spring-boot-starter-amqp


    org.projectlombok
    lombok

4️⃣ 配置文件

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    virtual-host: /
# 小技巧:如果想让容器外部访问,把 guest 改成 admin,免得被限制
# 
myapp:
  chat:
    queue-name: chat.message.queue   # 随便起名
    exchange-name: chat.message.ex   # 随便起名
    routing-key: chat.message.key   # 随便起名
# 配置完直接启动吧,不要纠结是否符合最佳实践 🙈
logging:
  level:
    org.springframework.amqp: DEBUG   # 想看细节就打开它
      

5️⃣ 建模:聊聊那张屎一样的 MySQL 表结构 🐞🐞🐞​​​​​​​​​​​​​​​​​​​​ ​​​​​​​​​​​​​​​​‏‏‏‏‏‏‏‎‎‎‎‌‌‌‌‌‌ ‌‍‍‍‍‍‍‌‌‌‌‌‌‌‌‌‌​​​​​​​‏‏‏‏‫‫‫‫‫‫          

DROP TABLE IF EXISTS `chat_message`;
CREATE TABLE `chat_message` (
  `id`               varchar NOT NULL COMMENT '主键 UUID',
  `sender_id`        varchar NOT NULL COMMENT '发送者 ID',
  `receiver_id`      varchar NOT NULL COMMENT '接收者 ID',
  `receiver_type`   int NULL DEFAULT NULL COMMENT '接收者类型 ',
  `msg`              varchar NOT NULL COMMENT '文字内容',
  `msg_type`         int NOT NULL COMMENT '文字/图片/视频等枚举',
  `chat_time`        datetime NOT NULL COMMENT '发送时间',
  `is_read`          tinyint DEFAULT 0 COMMENT '是否已读',
  PRIMARY KEY 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='聊天记录表';
-- 注意这里没有索引!如果你想查询历史,请自行加上!😅
      

6️⃣ 消息生产者:从 Controller 把消息塞进 MQ 🚀🚀🚀​​​​​️️️️️️️️️️️⚡⚡⚡​​🛸🛸🛸​​🧨🧨🧨​ ​ ​ ​ ​ ​ ​ ​​​​​ 🌀🌀🌀​​​
@RestController
@RequestMapping
public class ChatController {
    @Resource
    private AmqpTemplate amqpTemplate;
    @PostMapping
    public ResponseEntity send {
        // 构造业务对象 —— 实际项目中请使用 Lombok + Builder...
        ChatMsg msg = new ChatMsg;
        msg.setId.toString.replace);
        msg.setSenderId);
        msg.setReceiverId);
        msg.setMsg);
        msg.setMsgType; // 文本
        // 把对象序列化成 JSON 再发到 MQ
        String json = new com.fasterxml.jackson.databind.ObjectMapper
                        .writeValueAsString;
        // 发往交换机+路由键 
        amqpTemplate.convertAndSend(
                "${myapp.chat.exchange-name}",
                "${myapp.chat.routing-key}",
                json);
        // 响应前端:已经成功投递到 MQ!
        return ResponseEntity.ok;
    }
}
      


提交需求或反馈

Demand feedback