交易系统核心域拆分:订单域、账户域、风控域、清算域、行情域的边界划分
做交易系统微服务改造,第一步就是拆域。这一步要是拆错了,后面全是坑。我见过不少团队,上来就按功能模块切,结果服务之间互相调来调去,延迟比单体还高。
今天咱们就聊聊,交易系统的五个核心域——订单域、账户域、风控域、清算域、行情域——到底该怎么划边界。
为什么是这五个域?
你想想看,一笔交易从发生到结束,经历了什么?
- 行情域:提供价格信息,是交易的「眼睛」
- 订单域:接收用户指令,是交易的「手」
- 风控域:检查交易是否合规,是交易的「刹车」
- 账户域:管理资金和持仓,是交易的「钱包」
- 清算域:完成最终结算,是交易的「会计」
这五个域,各自负责一个完整的业务闭环。边界清晰,职责单一。我在项目中遇到过有人想把风控塞进订单域里,结果代码耦合得一塌糊涂,改一个风控规则要重启整个订单服务。
核心原则:每个域只做自己该做的事,不越界,不替别人操心。
订单域:交易的入口
订单域负责接收、校验、路由订单。说白了,就是用户说「我要买100股」,订单域负责把这句话变成系统能理解的结构化数据。
订单域的边界很清晰:
- 它不关心用户账户里有没有钱——那是账户域的事
- 它不关心这笔交易是否违规——那是风控域的事
- 它只负责把订单状态管理好:已接收、已校验、已路由、已成交、已撤销
嗯,这里要注意:订单域会调用风控域和账户域的服务,但调用方式是异步的。我习惯用事件驱动的方式,订单域发出「订单创建」事件,风控域和账户域各自监听处理。这样即使风控服务挂了,订单也不会丢。
账户域:资金和持仓的管家
账户域管理用户的资金余额、冻结金额、可用金额,以及持仓数量。这个域对数据一致性要求极高,因为涉及到钱。
边界划分上:
- 账户域只负责记账,不负责算账——算账是清算域的事
- 账户域只管理「可用」和「冻结」两种状态,不关心订单的成交细节
- 账户域提供的是「查询余额」和「冻结/解冻资金」这样的原子接口
我曾经犯过一个错误:在账户域里直接做了订单的成交逻辑。结果订单状态和账户余额对不上,排查了整整两天。后来我学乖了,账户域只做加减法,不做业务判断。
风控域:交易的守门员
风控域负责检查每一笔交易是否合规。比如:
- 用户是否在交易黑名单里
- 交易金额是否超过单笔限额
- 交易频率是否异常
- 是否涉及内幕交易嫌疑
风控域的边界很特殊——它不产生业务数据,只做判断。所以它的接口设计应该是「纯函数」风格:输入订单信息,输出通过/拒绝。
个人经验:风控规则变化频繁,建议把规则引擎独立出来。我习惯用Drools或者自研的规则引擎,这样业务人员也能自己配规则,不用每次都找开发改代码。
清算域:交易的收尾人
清算域负责在交易成交后,完成资金和证券的划转。这个域是典型的「事后处理」——它不参与交易过程中的实时决策,只做最终结算。
边界划分要点:
- 清算域只处理「已成交」的订单,不关心订单是怎么成交的
- 清算域需要和账户域交互,但交互方式是批量对账,不是实时调用
- 清算域的数据一致性要求极高,通常采用TCC(Try-Confirm-Cancel)模式
说白了,清算域就是交易系统的「会计部」。它不着急,但必须准。
行情域:交易的眼睛
行情域负责提供实时的市场价格信息。这个域比较特殊,因为它不直接参与交易流程,但所有交易决策都依赖它。
边界划分上:
- 行情域只负责「推送」数据,不负责「消费」数据
- 行情域的数据是「流式」的,不是「请求-响应」式的
- 行情域不关心谁在用它的数据,也不关心数据被用来做什么
我建议行情域单独部署,使用独立的网络带宽和计算资源。因为行情数据量极大,如果和其他域混在一起,很容易互相影响。
域间通信:怎么让它们好好说话?
域拆好了,接下来就是怎么让它们协作。我总结了几种常见的通信模式:
| 通信场景 | 推荐方式 | 原因 |
|---|---|---|
| 订单域 → 风控域 | 异步事件 | 风控判断不阻塞订单接收 |
| 订单域 → 账户域 | 异步事件 | 资金冻结需要时间,不能阻塞 |
| 清算域 → 账户域 | 批量对账 | 保证最终一致性 |
| 行情域 → 其他域 | 消息队列广播 | 一写多读,解耦 |
避坑指南:千万不要在域之间使用同步RPC调用。我曾经在一个项目里,订单域同步调用风控域,结果风控服务响应慢了,订单服务线程池被打满,整个系统雪崩。后来改成异步事件,问题就解决了。
一张图看懂五个域的边界
下面这张图展示了五个核心域的关系和边界。我用SVG画的,你可以直接复制到你的文档里。
总结一下
域拆分这件事,说白了就是「高内聚、低耦合」的实践。每个域只关心自己的业务逻辑,通过事件或消息与其他域协作。
我个人习惯在拆分时先画一张「业务流程图」,把每个步骤的输入输出标清楚。然后问自己一个问题:「如果这个服务挂了,会影响哪些其他服务?」 如果影响范围太大,说明边界没划好。
最后说一句:域拆分不是一蹴而就的。刚开始可以粗一点,随着业务发展再逐步细化。关键是保持边界清晰,别让代码变成一锅粥。
公众号:蓝海资料掘金营,微信deep3321