**订单中心
作为我参与的第一个与“三高”关系较为密切的业务“订单中心”,在这篇文章中记录一下其中参与开发的业务流程中涉及的技术栈和技术难点,从实践的角度去理解“三高一海”业务场景下是如何运用各种技术栈来解决业务问题的。
1.多级缓存
这里仅对我了解的一个业务流程进行概述,主题是做订单消息接入。我们作为下游接收上游消息队列的消息,首先定义并创建一个适配器类,将从各种来源的订单信息转换为标准的订单格式,方便进行标准和统一的处理。这个过程中,需要解析json,并需要从业务侧查询部分信息作为订单信息的补充。在这里,由于是直播的一个场景,所以需要查询直播id,考虑到每次都到业务侧去查询会给业务侧带来较大的流量和数据库压力,这里采用了缓存,并且是二级缓存。
第一级缓存是redis,从内存中去查询订单id+订单来源所对应的直播id,第二级是一个分布式存储中间件,最后才是从业务侧去调用接口查询DB作为兜底。可以极大提升查询效率,大部分请求都能在高速缓存命中,极大减少对下游业务接口和数据库的压力。
Redis 作为第一级缓存,查询速度极快(毫秒级),适合高并发、热点数据的快速访问。分布式存储中间件作为二级缓存,容量大、可扩展,提升缓存命中率,进一步降低访问后端DB的频率。
2. 分布式锁
经过上一步构建订单基本信息后,进行基本的数据校验,保证信息没有格式问题后,接下来需要从DB和业务侧查询订单信息,并构建订单的完整更新信息,最后再持久化并发送订单事件信息。这个过程涉及订单更新,属于写操作,那么就要注意控制并发行为,防止一个订单被同时修改,导致数据不一致的问题。
通过分布式锁,可以防止多个线程同时进入该方法去修改订单。具体行为逻辑是,通过订单id+订单来源作为锁名称来控制锁粒度,并设置一个锁的过期时间,重试次数。
3. SPI注册发现
订单处理往往包含一些统一的方法,如根据订单id查询订单信息、根据订单id查询退款、履约、直播间信息等。但由于存在不同的业务侧,具体的查询逻辑不尽相同,为了更好地维护这些接口,使用了SPI注册发现机制。在调用接口,如查询订单信息接口,首先会根据订单来源去发现具体的接口实现类(遍历所有注册的订单查询接口实现类),匹配对应的接口实现类,再去调用具体的实现方法,实现了将业务实现策略和业务解耦,当需要处理新的订单来源时,只需要把新的接口实现类去用注解自动注入即可,大大减少了代码的冗余。
这样的实现符合开闭原则,系统对扩展开放,对修改封闭。新业务扩展只需新增实现,无需动核心代码,降低了回归测试和维护成本。
4. 事务控制
订单构造完毕后,需要导入db进行持久化,这个过程涉及多个db操作。完成持久化后还需要使用消息队列将消息发送至下游周知,整个过程需要进行事务控制,如果出现部分成功,会导致数据不一致的问题,引发订单错误。值得注意的是,除了各个数据表之间进行事务控制外,如果消息发送出现问题抛出异常,也会进行回滚,保证各个业务方的数据一致性。
通过将订单多表持久化和消息通知纳入同一事务控制范围,能够有效保障业务数据一致性、提升系统鲁棒性、降低补偿成本、优化用户体验,并为系统扩展和分布式演进奠定坚实基础。