大宗商品销采运储系统・六层架构连载(公共中间件层)
上一篇,我们完成了配置中心的落地拆解。注册中心解决服务寻址,配置中心管理动态参数,而消息队列,是分布式系统里用来做异步通信的核心底座。
在大宗商品销采运储业务中,单据流转、入库出库、对账推送、第三方系统对接,大量业务都是脉冲式流量。白天业务高峰,大量订单、仓储单据集中产生;夜间批量对账、数据同步任务集中执行。如果全部采用同步调用,很容易出现接口超时、服务雪崩,上下游强耦合,一个系统慢,整条链路跟着卡住。
消息队列的核心价值,一句话概括:
把同步强依赖,转为异步解耦;把瞬时尖峰流量,平滑成持续稳定的消费流量。
一、消息队列在销采运储业务中的核心职责
消息队列主要负责四件事:
-
业务解耦:采购、销售、仓储、运输、财务对账各个业务服务之间不再直接同步调用。上游业务完成后投递消息,下游按需消费。上游不需要关心下游是否在线、处理快慢。例如销售下单成功,投递消息,仓储服务异步生成入库单、财务异步生成应收单据,互不阻塞。
-
削峰填谷:业务高峰期瞬时涌入大量单据,消息队列作为缓冲,先把消息存储下来。消费端按照自身处理能力匀速消费,避免瞬间流量压垮下游服务。比如大宗商品集中开盘下单、月底大批量对账场景。
-
异步通知:跨系统对接场景,推送外部平台单据、回调通知、状态变更提醒,全部走消息队列,不阻塞主业务流程。
-
事件回溯与可靠投递:业务事件持久化存储,消费失败可以重试;出现业务问题,可回溯事件记录,排查单据流转断层问题。
边界说明:
消息队列只负责消息的存储、投递、重试,不承担业务逻辑。业务幂等、单据状态校验,依然需要业务服务自己实现。

二、整体架构与基础消息流转链路
整套基础链路分为生产者、Broker 集群、消费者三大部分。
-
业务服务(生产者)完成核心业务逻辑,组装业务事件消息,投递至消息队列 Broker 集群。
-
Broker 持久化消息,写入磁盘,支持多副本,保证消息不丢失。
-
消费者服务订阅对应 Topic,拉取消息进行业务处理。
-
业务处理成功,提交消费位点,Broker 标记消息已消费。
-
业务处理异常,不提交位点,按照策略重试;多次失败,消息转入死信队列,人工排查,避免无限重试阻塞队列。
核心设计要点:
-
集群多副本部署,防止单点故障;
-
消息位点持久化,服务重启之后,从上次消费位置继续处理;
-
区分普通业务 Topic、死信 Topic、重试 Topic,隔离异常消息,不污染正常业务消息。

三、销采运储场景选型对比
大宗商品销采运储系统,存在内网信创部署、大批量单据、高可靠要求,这里做选型对比:
| 中间件 | 适用场景 | 优点 | 业务局限 |
|---|---|---|---|
| RocketMQ | 企业业务单据、对账、事件通知 | 支持事务消息、死信、重试,运维成熟,适合业务事件 | 资源占用相对高 |
| Kafka | 海量日志、大批量流式数据 | 高吞吐,适合数据采集场景 | 事务消息能力弱,不适合核心单据流转 |
| RabbitMQ | 简单异步通知,路由灵活 | 易用,路由模型丰富 | 大批量消息场景吞吐量一般 |
本项目选型:RocketMQ。
核心单据流转、跨业务事件全部使用;日志采集等大数据流量场景,单独使用 Kafka,两类场景分开,不混用。
基础 Spring Boot 接入示例
pom.xml 依赖:
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.3</version>
</dependency>
application.yml 配置:
rocketmq:
name-server: 10.0.0.20:9876;10.0.0.21:9876;10.0.0.22:9876
producer:
group: supply-producer-group
consumer:
group: stock-consumer-group
生产者发送消息:
@Autowired
private RocketMQTemplate rocketMQTemplate;
// 销售下单完成,投递仓储事件
public void sendOrderStockEvent(OrderStockDTO dto) {
String topic = "supply_order_stock_topic";
rocketMQTemplate.convertAndSend(topic, dto);
}
消费者监听消息:
@RocketMQMessageListener(
topic = "supply_order_stock_topic",
consumerGroup = "stock-consumer-group"
)
public class StockOrderConsumer implements RocketMQListener<OrderStockDTO> {
@Override
public void onMessage(OrderStockDTO message) {
// 仓储业务处理,生成入库单据
stockService.createStockOrder(message);
}
}
工程规范:
Topic 命名必须带业务域前缀,例如
supply_order_stock_topic、sale_outbound_topic、logistics_track_topic。禁止无业务语义的test_topic、topic1上线。
四、本篇小结
本篇我们理解了消息队列的定位、基础流转模型,以及销采运储场景下的组件选型与基础代码接入。
记住一句话:
消息队列不是"发个消息就完事",它解决的是上下游解耦、流量削峰、事件可靠投递。
但在大宗商品核心单据场景,仅仅基础消息能力远远不够。单据一致性、事务消息、消息幂等、堆积治理、消息监控这些生产级难题,才是落地的重中之重。
下篇预告:消息队列(中篇):事务消息、幂等设计、消息堆积与死信治理,拆解大宗商品单据流转的生产级实战方案。