大宗商品销采运储系统・六层架构连载(业务服务层)
前面我们用大量篇幅,完成了基础服务层、公共中间件层、数据持久层这三大底层硬核模块的搭建。
地基打好了,接下来我们将正式进入整个六层架构的最核心、也是直接产生商业价值的一层:【业务服务层】。
大宗商品(钢铁、煤炭、化工、农产品等)的业务非常复杂:涉及多式联运、货权转移、期现结合、批次质检、智能过磅等特有逻辑。很多团队一上来就开始画表、建接口,结果系统越写越乱,最终变成了几十个微服务互相疯狂调用、牵一发而动全身的“分布式单体”。
一句话定调:
业务服务层不是写 CRUD,而是画业务边界。用 DDD(领域驱动设计)约束微服务的膨胀,用防腐层隔离外部生态的污染,才是大宗商品交易的架构底座。
一、痛点:微服务拆分,为什么总是拆成“分布式单体”?
很多架构师在业务层落地时,容易踩进四个致命误区:
按部门拆分(组织架构绑架技术架构):采购部一个系统、销售部一个系统。结果一搞集中开盘,销售要查采购的实时库存,只能跨系统调接口,接口一挂全盘崩溃。
按表拆分(伪 DDD):有订单表就建订单服务,有明细表就建明细服务。导致一个“查询订单详情”的请求,要跨 5 个微服务做 Join,响应慢如老狗。
按技术分层拆分(极端的过度设计):建了 Controller 微服务、Service 微服务、DAO 微服务。一次请求要在网络里流转三次,网络开销直接把性能拖垮。
纳米级微服务(粒度太细):把客户、客户联系人、客户银行账户拆成三个独立服务。导致业务逻辑被切碎,分布式事务满天飞。
大宗商品平台是一条强耦合的物理与资金链条:期现套保 → 采购长协 → 物理仓储 → 过磅质检 → 运输履约 → 销售变现 → 财务结算。如果边界切错了,后续的分布式一致性和长链路追踪会让你痛不欲生。

二、大宗商品平台全景图:我们到底在管什么?
在看代码之前,先看业务。大宗商品平台绝不仅仅是“买进卖出”,它涵盖了复杂的金融属性、物理属性与生态协同。
┌────────────────────────────────────────────────────────────────────────┐│ 【外部生态与协同层】 供应商门户 | 客户自助终端 | 司机小程序 | 第三方物流对接 │└────────────────────────────────────────────────────────────────────────┘ │ ▼┌────────────────────────────────────────────────────────────────────────┐│ 【交易与商务域】 ││ 询价报价 | 长协框架 | 现货挂牌 | 集中竞价 | 期现结合(套保) | 电子合同签署 │└────────────────────────────────────────────────────────────────────────┘ │ ▼┌────────────────────────────────────────────────────────────────────────┐│ 【履约与物流域】 ││ 提货单流转 | 派车调度 | 多式联运 | 场站门禁 | 智能过磅 | 电子围栏 | 轨迹追踪 │└────────────────────────────────────────────────────────────────────────┘ │ ▼┌────────────────────────────────────────────────────────────────────────┐│ 【仓储与物权域】 ││ 多货主隔离 | 库位管理 | 批次/炉号管理 | 质量化验(质检) | 货权转移 | 仓单质押 │└────────────────────────────────────────────────────────────────────────┘ │ ▼┌────────────────────────────────────────────────────────────────────────┐│ 【风控与金融域】 ││ 客户信用评估 | 授信额度管控 | 保证金冻结 | 预付款释放 | 资金流水对账 │└────────────────────────────────────────────────────────────────────────┘ │ ▼┌────────────────────────────────────────────────────────────────────────┐│ 【业财与协同域】 ││ 应收应付 | 开票(金税) | 银企直联 | 客诉工单 | 异常审批流 | 财务总账(对接ERP) │└────────────────────────────────────────────────────────────────────────┘
从全景图可以看出,大宗商品真正的核心业务域不仅包含基础的销采运储,还要深度嵌入风控、金融和业财一体化。

三、DDD 落地第一步:划分限界上下文(Bounded Context)
DDD 的核心思想是:微服务不是按“表”拆,也不是按“前端菜单”拆,而是按“业务能力的边界”拆。
结合大宗商品特点,我们把系统划分为五大核心限界上下文:
交易上下文:核心域。只管商务行为(客户报价、销售开单、采购寻源、合同生成)。
履约上下文:支撑域。只管物理执行(发货指令、派车调度、多式联运、过磅防作弊)。
库存上下文:核心域。只管物权与数量(批次管理、库位分配、货权转移、盘点)。
风控与金融上下文:支撑域。只管钱的安全(信用额度校验、保证金冻结与释放)。
业财上下文:通用域。只管对账与开票(应收应付、发票开具、财务凭证生成)。
上下文之间怎么交互?
绝对不允许直接读对方的数据库(微服务红线)。必须通过 领域事件(Domain Event) 或 RPC 接口。
例如:销售开单成功,交易上下文发布一个 OrderCreatedEvent,履约上下文监听到后,生成派车任务;风控上下文异步扣减客户授信额度。

四、DDD 落地第二步:聚合根(Aggregate Root)设计
在微服务内部,单据表怎么设计?大宗商品的单据头(Order)和单据明细(OrderItem)必须放在一起,不能拆成两个服务。在 DDD 中,这叫聚合(Aggregate)。
以“销售订单”为例:
-
聚合根(Aggregate Root):销售订单。它是外部访问的唯一入口。
-
实体(Entity):订单明细、提货指令。它们依附于订单存在。
-
值对象(Value Object):价格(金额+币种)、重量(数值+单位)、化验指标。修改必须全量替换。
聚合根核心代码示例:
@Entity
public class SaleOrder {
@Id
private String orderNo; // 采用持久层讲过的雪花算法生成
private String customerId;
private OrderStatus status;
// 强关联的子实体集合
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> items;
private Money totalAmount;
// 业务行为:创建订单
public void createOrder() {
// 1. 校验客户信用额度 (调用风控域接口)
// 2. 校验实时库存 (调用库存域接口)
// 3. 计算总价与保证金
// 4. 触发领域事件:OrderCreatedEvent
}
}
业务规范:外部服务(如财务系统)想要查某个订单,必须通过 SaleOrderService 去查,绝对不允许直接写 SQL 操作 t_order_item 表。
五、DDD 落地第三步:防腐层(ACL)隔离外部生态的“烂代码”
大宗商品平台是个巨大的集成中心。除了老旧的 ERP、财务共享系统、第三方物流平台、电子发票系统等。
如果你直接把对接硬件的代码写在“库存域”,把对接期货的代码写在“交易域”,系统立刻变成意大利面条。
我们需要引入防腐层(Anti-Corruption Layer, ACL)。
[业务核心域] │ 调用 IssueInvoiceUseCase (内部领域接口) ▼[防腐层 ACL (独立的 Integration 微服务)] │ 1. 模型转换:将内部过磅单转为地磅硬件协议 │ 2. 协议适配:将 HTTP 转为 TCP/IP / WebService / MQ │ 3. 异常重试与硬件防抖 ▼[外部生态环境:电子发票/银企/物流/物联网设备]
设计原则:不管外部系统或硬件长什么样,业务域内部永远只认自己的领域模型。外部系统的变化被死死挡在防腐层里。

六、业务层与前文底座的联动(绝不是在孤岛上写代码)
我们在写业务层时,绝不是从零开始,而是要时刻调用前面建好的底座:
与中间件联动:交易域开单成功后,不直接调用履约域接口,而是发一条 OrderCreatedEvent 到 RocketMQ,由履约域异步消费,实现业务解耦。
与持久层联动:在创建订单的聚合根时,订单号直接调用持久层篇中讲过的雪花算法(Snowflake)生成,且 ID 的低 4 位直接嵌入客户 ID 的基因,方便后续分片路由。
与基础服务联动:所有开单接口必须强制接入接口服务(幂等控制),防止用户重复点击导致重复下单。
七、本篇小结
业务服务层是系统的“发动机”。不要上来就写接口,先画图,先定边界。
记住三句话:
业务拆分靠 DDD,按限界上下文划界,不能按表拆、不能按部门拆。
单据设计用聚合根,内部强一致性,外部只能访问根节点。
外部生态对接必须有防腐层,决不让 ERP、税控、物联网硬件的烂代码污染核心架构。
下篇预告:业务域基建(上):复杂单据状态机设计,拆解如何用状态机引擎彻底消灭海量的 if-else,并保证业务流转的严格合规?
网硕互联帮助中心



评论前必须登录!
注册