思维导图
实战汇总
交易中心
整体图示
- 订单服务: 下订单等功能
- 支付服务: 主要跟第三方对接,比如微信支付,支付宝支付,还有51社保等
- 售后服务: 比如退款等功能
- 开票服务: 订单完成之后需要开发票
- 结算服务: 比如用户在淘宝买完东西后,订单是在淘宝这边,但是最终还是要给商家结算钱款
- 对账服务: 分为实时对账,T+1对账。这块可以大数据处理,实时使用Flink,离线使用Spark,对第三方服务的流水进行自己服务对比,数据不匹配则报警
部分ER图
- 简单的,没有拆单的交易系统全貌。
- 订单表Order,与订单收货地址表是一对一关系,即一个订单只有一个收货地址; 与订单优惠表是一对多关系,一个订单可以有多张优惠券; 与订单商品表也是一对多关系,一个订单可以有多个商品; 与订单运单表是一对一关系,一个订单只有一个物流信息; 与费用表也是一对一关系,一个订单支付方式啥的是唯一的; 与退款单也是一对一的关系如果有退款的话。当时订单优惠表,订单商品都是跟优惠系统/商品系统id关联
- Refund: 退款订单表,与订单是一对一的关系; 与费用表也是一对一关系,一个订单支付方式啥的是唯一的
- 支付信息表Payment_info: 与费用表是一一对应关系
- 这里只展示部分ER图
订单服务
商品详情页点点去支付时生成订单
1.1 看是否在黑名单: Flink实时数据判断用户是否有非法操作,有的话写入风控
1.2 获取SPU: 需要去商品服务获取
1.3 获取优惠信息: 需要从优惠服务获取
1.4 订单生成
1.5 完成后跳支付方式页面
支付服务
选择支付方式后的下一页,订单支付
1.1 看是否在黑名单: Flink实时数据判断用户是否有非法操作,有的话写入风控
1.2 收银台支付: 调用支付服务,支付服务调第三方支付
1.4 异步回调结果: 第三方服务异步回调
1.5 更新支付状态: 支付服务更新状态
1.6 支付成功发MQ: 成功后发MQ。MQ通过事务表保证最终一致性保证,或者类似RocketMq这种带事务的MQ。
2.1 前端轮询是否完成支付
2.2 选择支付方式后下一页提交订单,这时候锁库存,根据店铺进行拆单,支付时同时支付,支付单关联多个订单id
2.3 物流服务,权益服务: 如果监听MQ支付成功,则处理MQ消费如果订单是有实物类型则需要发送货物并标记已发货,权益服务一样处理方式。这里要做好幂等处理
结算服务
- 结算服务,比如淘宝商家,玩家买商品之后,淘宝平台需要结算给商家, 这种是需要关联订单id的。还有如猪八戒网等接单平台,也是需要结算
51社保对接流程
-
一般我们会选择第三方平台作为对接平台,因为涉及报税等操作,这里我们选择51社保作为对接平台
- 获取access_token,因为涉及第三方对接,所以在签署完合同会获取到access_key(确定业务方是谁)和access_secret,通过key和secret获取到有时效性的access_token
- 携带access_token获取发放结算单的配置
- 调用单笔发放结算单接口,这里51社保会做幂等处理
- 51社保异步回调通知,这里是通过回调地址的方式通知,51社保有做补偿最多好像是15次,最后一次间隔15h。这里只是通知状态变更,具体的明细状态还需要通过查询明细接口获取。不直接回调全部结果是因为对于51社保的业务方提供的回调地址可能是http的不安全。这里回调是51社保提供了sign,业务方可检验sign保证是51社保回调的
- 如果超过一天未回调需要主动查询,这里简单做可以通过线程扫表的方式处理
- 大数据,离线统计对账业务侧数据结算单和51社保对应的明细单,减少财务人工对账出错概率
51社保报税
-
公司业务是设计师接单,然后获取接单的钱,可以提现,提现涉及结算。这里结算涉及报税
财务在51社保上转账
-
提前转正,有管理后台给财务使用
转账业务一致性保证
可靠消息最终一致性
- A 系统先向 mq 发送一条 prepare 消息,如果 prepare 消息发送失败,则直接取消操作
- 如果消息发送成功,则执行本地事务,不一定是插入数据库,也可以是发MQ消息
- 如果本地事务执行成功(或者发MQ成功),则向 mq 发送一条 confirm 消息,如果发送失败,则发送回滚消息
- B 系统定期消费 mq 中的 confirm 消息,执行本地事务,并发送 ack 消息。如果 B 系统中的本地事务失败,会一直不断重试,如果是业务失败,会向 A 系统发起回滚请求
5.mq 会定期轮询所有 prepared 消息调用系统 A 提供的接口查询消息的处理情况,如果该 prepare 消息本地事务处理成功,则重新发送 confirm 消息,否则直接回滚该消息
TCC转账
- 汇款服务
1.1 Try:检查A账户的有效性;检查A账户的余额是否充足;从A账户中扣减100元,并将状态置为转账中;预留扣减资源,将从A账户向B账户转账100元这个事件存入消息或日志
1.2 Confirm:不做任何操作
1.3 Cancel:A账户增加100元;从日志或消息中释放扣减资源。 - 收款服务
2.1 Try:检查B账户的有效性
2.2 Confirm:读取日志或者消息,B账户增加100元;从日志或消息中释放扣减资源
2.3 Cancel:不做任何操作
退款服务
- 用户在app上选择退款
- 客服系统生成工单并进行审核,审核通过下一步
- 判断退款时效性,如果时效符合要求,则进行下一步,在订单系统创建退款单,这里要关联订单
- 如果涉及退货,则需要物流系统正常收到货之后,重新发货,或者直接退款
秒杀服务
秒杀上架前
- 一般秒杀商品上架前会有个公示期,比如半小时前提前展示,但秒杀活动未开始
- 定时查询需要上架的秒杀商品
- 封装秒杀商品信息到redis
- 设置秒杀商品库存,可以用redis信号量
秒杀
- 除了redis外,还可以用本地缓存 + redis, 先缓存本地缓存锁,再获取redis锁,获取后再扣减redis库存,一般本地缓存稍微多一点
- redis和mq一致性保证,一致性保证服务监听redis AOF日志,对吧监听发送的MQ,校验,然后处理
- 主要限流,降级,熔断处理
-
秒杀服务一般单独一个服务避免影响其他服务
- 秒杀页面缓存到CDN
- 前端秒杀验证码验证
- nginx动静分离
- 网关系统sentine限流,可以通过ip限流等
- 用户秒杀到秒杀服务,秒杀服务会校验合法性,获取redis锁,然后扣减库存,然后发MQ,比如rocketmq是有事务保证。也可以监听redis aof日志做对账
- 订单服务消费MQ生成订单
对账服务
对账系统保证账务一致性
- 比如需要实时对比,则可以考虑Flink实时拉取canal订单表更,再监听第三方回调流水,横向对比,有问题及时告警。当时也可以选择离线T+1对比,本质是一样的
对账系统数据库和ES一致性保障
-
一致性服务通过接收来自上游canal发送的bp消息,以及帐房系统写入es成功后发送的bp消息,将二者的消息存储至mysql数据库中,每日定时对上下游系统的数据进行对比分析,得出对应的差异数据,然后通过调用对应的修复接口完成数据的修复。Spark生态可以进行离线计算定期统计交易信息
数据聚合
-
百度技术文章里面是用大数据处理报表生成,通过spark拉取es的集群数据,存储在AFS上