一、旧系统的现状分析:
1)服务调用关系
2)接口梳理
订单相关旧系统接口整理:
a、gamecatsdk服务
b、wechat服务
c、paysdk服务
d、paycenter服务
主要梳理的格式包括:
接口名称;接口uri;接口被调用服务;接口网络访问(内网还是外网);迁移后的服务;重构后新接口URI。
(具体的梳理省略,每个公司每个系统的情况各不一样。)
3)ER关系图
二、新系统的设计
1)ER图:
2)域名依赖关系:
paycenter的域名是:paycenter.xxx.com
trade的域名是:trade.xxx.com
a、支付回调。为了支持旧系统已发起的支付(支付宝和微信),在trade-nginx配置旧域名paycenter.xxx.com的调用。也就是说,无论是paycenter.xxx.com还是trade.xxx.com都指向trade-nginx服务器。
注意:在开发测试环境里,trade服务需要开通对外端口映射,让支付机构能够回调到trade-nginx。
b、IOS内支付回调,为了兼容旧版本的客户端回调服务后端,之前是访问paycenter.xxx.com /notify/iosInnerPay,所以trade-nginx需要支持paycenter.xxx.com/notify/iosInnerPay。
3)数据迁移:
由于旧系统的订单和代金券也是分库分表,需要先使用临时表,把之前的分库聚合到一张临时表。再根据主键ID%n的方式分到新的库里。
在预防环境下执行, 数据迁移分为三类数据,包括基础类,订单类和支付类。
等新服务上线验证无误后,执行补偿任务,把落在旧库的订单和支付等数据再次补偿到新库。
I、基础数据
支付接口实现 pay_api :
支付接口映射:pay_api_mapping
ios sdk商品:sdk_ios_goods
II、支付数据
支付流水:pay_flow
支付通知:pay_notify
ios支付校验 pay_ios_voucher_check
III、订单数据
订单:order_base
喵点订单:catpt_order_detail
sdk订单:sdk_order_detail
订单索引表:order_es_index
订单代金券使用表:order_use_coupon
4)因为订单分库分表了,之前为了解决跨库聚合问题,引入的是订单索引表。
后期引入分布式搜索引擎ElasticSearch。
mysql数据库负责的是操作类,ES负责订单查询,分页查询等。
做过分库分表的重构同学,都得面临解决旧库与新库的一致性问题。常见的解决方案有:
I、停机部署
挂出停机公告,届时进行数据迁移,待验证通过后,切流到新库。
II、双写到db和mq
历史数据
增量数据:保存在mq里,通过订阅程序把增量数据补到新库。
III、双写到db和ES
采用cqrs思想,把操作类和查询类分离开来,新库和旧库都会写入ES, 避免查询数据的同步延迟等问题,保证用户看到的订单数据是实时的,也不影响运营后台的订单管理。
mysql里的数据采用补偿机制,把旧库的增量数据同步到新库。
建议方案三,可以不用停机部署,至于灰度策略问题,等后续专门文章来讨论。
在迁移期间,旧程序和旧库表务必保留,不能删除,否则会出现订单或支付流水号找不到的错误等等。新系统必须是对新旧的一个同时兼容,只有待程序运行确保无误后,再删程序删库表。