Skip to content

🎤 面试官:你做过订单相关的开发吧?说说用户下单之后,系统是怎么处理的?

: 嗯,我们平台用户下单付款之后,不是直接就“待发货”了,中间还得走一套叫“履约”的流程。

比如你买个手机,付完钱,系统得先看看库存够不够、价格有没有被人改过、是不是黄牛账号、商家同不同意接单……这些都通过了,才算真正“接单成功”,才能推给仓库去发货。

这一套流程,就是我们说的“订单履约”。


🎤 面试官:那这个流程是同步还是异步?为啥?

: 是异步的,靠消息队列驱动。

为啥呢?你想啊,用户付完钱,如果系统当场卡那儿去查库存、调风控、推仓库,一卡就是几百毫秒甚至几秒,用户体验就崩了——“我钱都付了,怎么还没进待发货?”

所以我们是这么设计的:

  • 用户一付款,支付系统发个消息到 RabbitMQ,说“XXX订单付钱了”;
  • 我们的履约服务监听这个消息,收到后慢慢处理;
  • 用户端看到的是“支付成功”,后台在悄悄干活。

这样前端快,后端稳,各干各的,不打架。


🎤 面试官:那如果消息重复了,会不会重复处理?比如库存扣两次?

: 会啊,MQ 本来就会重试,网络抖一下、服务重启一下,消息就可能重复。

所以我们做了三道保险:

  1. 看订单状态:比如我收到消息,先查一下这订单现在是啥状态。如果已经变成“待发货”或者“履约中”了,那说明处理过了,直接跳过;
  2. Redis 标记:处理之前,先往 Redis 里写个 fulfillment:done:订单ID,设个过期时间。下次再来,发现已经有这个 key,就不干了;
  3. 数据库唯一约束:比如生成发货单的时候,用 订单ID 做唯一索引,重复插入直接报错,不会多生成。

三招一起上,基本就能保证“同样的事,干一遍就够了”。


🎤 面试官:库存是怎么锁的?会不会超卖?

: 库存这块我们挺小心的,用的是“先冻结,后扣减”的模式,有点像你去餐馆吃饭,服务员说“您稍等,我帮您看看还有没有座”。

具体是这样:

  • 用户下单付钱后,我们调库存服务,说“先给我把这个商品锁住,别让别人买了”;
  • 库存服务就把可用库存减 1,加到“冻结库存”里;
  • 等履约成功了,再把冻结库存正式扣掉;
  • 如果中间出问题(比如风控没过),就解冻,库存还回去。

这种方式叫 TCC(Try-Confirm-Cancel),虽然麻烦点,但能保证不超卖。 要是直接“扣库存”,万一后面流程挂了,用户钱付了货发不了,那就出大事了。


🎤 面试官:那如果调仓库系统(WMS)失败了,怎么办?

: 这个太常见了,WMS 接口不稳定、网络超时、对方系统抽风……我们都遇到过。

我们的做法是:不卡住主流程,先记下来,回头慢慢补

具体是:

  • 履约走到最后一步,要推发货单给 WMS;
  • 调用失败了,我们不直接报错,而是把这条“推送任务”记到数据库一张表里,状态标成“失败”;
  • 然后有个定时任务,每隔 5 分钟扫一遍这张表,把失败的重新推;
  • 重试 3 次还不行,就发个企业微信消息给运维:“兄弟,XXX订单推不进去,赶紧看看”。

这样既不影响用户,又能保证数据不丢。


🎤 面试官:你们用什么跑定时任务?@Scheduled 行不行?

: @Scheduled 啥的,小项目玩玩还行,我们这种多台机器部署的系统,真不敢用。

为啥? 比如我们有 4 台订单服务,每台都写了 @Scheduled,那这个任务就跑了 4 遍,数据全乱了。

所以我们用的是 XXL-JOB,一个开源的分布式任务调度平台。 它有个控制台,可以:

  • 看任务有没有跑成功;
  • 手动触发;
  • 失败了自动重试;
  • 还能分片,比如把 100 万条数据分给 4 台机器各处理 25 万,提速。

就像公司打卡一样,以前靠员工自己记,现在用钉钉统一管,靠谱多了。


🎤 面试官:整个流程出错了能 rollback 吗?

: 完全 rollback 很难,因为涉及多个系统,比如库存、风控、WMS,不可能搞分布式事务锁一路到底。

我们的做法是:出问题不硬 rollback,而是走补偿

比如:

  • 如果库存锁了,但后面发现是黄牛,那我们就调个“解冻库存”的接口,把锁的还回去;
  • 如果已经推了 WMS,但订单取消了,那就得人工去仓库系统点“取消发货”;
  • 所有操作都记日志,出了问题能查清楚是哪一步卡了。

说白了,系统尽量自动化,但也要接受“人工兜底”,毕竟现实世界没那么完美。


🎤 面试官:你觉得这个系统最难的是啥?

: 我觉得最难的不是技术,是怎么让各个系统之间“不扯皮”

比如:

  • 库存系统说“我锁了”;
  • 风控说“我过了”;
  • 结果 WMS 说“我没收到”;
  • 最后用户打电话投诉“为啥还不发货”?

所以我们后来加了很多对账机制

  • 每天凌晨跑个脚本,看看“履约成功”的订单,有没有没推到 WMS 的;
  • 发现不一致,自动补推 or 告警;
  • 所有关键步骤打日志,用 SkyWalking 能链路追踪。

技术可以堆,但数据一致性得靠机制+监控+人一起守。