交易系统架构

  1. 云栖社区>
  2. 博客>
  3. 正文

交易系统架构

小飞哥1112 2018-04-15 15:16:58 浏览3245
展开阅读全文


一直以来表达能力都是自己的短板,不知道如何分享出自己觉得比较好的设计,所以决定好好的整理一下这几年使用的架构,以一种更加简单、清晰的思路将之前工作中的系统设计分享给大家。这是第一篇,后面会持续分享。

本博客主要从架构层面讨论交易系统的设计,不涉及细节。细节内容可以参考交易体系-交易、支付、物流、退款退货

一 主要内容

本博客主要从以下几个方面讲述交易系统架构:

交易系统的业务域是什么?即交易系统应该负责那些内容。

面对多样性的业务场景,交易系统如何承接他们?即交易系统的业务扩展性如何保证。

交易系统的复杂性问题,以及如何处理,特别是业务、系统解耦问题。

事件驱动流程。

简述高并发与高可用技术。

二 交易

首先我们聊聊什么是交易,以及交易系统的业务域。

1.   概念

交易是一种行为:是buyer在某一时间以某一价格购买了seller的一个或多个商品。现实世界中,这种行为是价值的交换;系统中,这种行为产生的是订单。

订单是一种契约:这种契约要求买卖双方按照订单的内容进行履约。以实物商品交易为例,buyer需要付钱契约才有效,seller需要将商品寄送给buyer。

交易至少涉及以下模型:买家、卖家、订单。

2.   交易

以实物商品交易为例,交易包括以下环节:

b5d19062c2ac282870714cd46a22594a9f047440

注意:这是一个完整的交易涉及的业务,但如果将以上所有业务都放在一个系统中却是一个非常糟糕的注意,后面会详细讨论此点。

3.   业务域分析

1)    下单

卖家必须有某个商品才能卖给买家,所以交易必然需要与商品系统打交道。为了让买家掏腰包,卖家、平台会想方设法的使用各种营销手段,吸引并促进交易的达成。常见的营销手段有:优惠(单品优惠、跨类目优惠、店铺优惠、平台优惠以及其他的组合方式);优惠券(单品优惠券、跨类目优惠券、店铺优惠券、平台优惠券以及其他组合方式);使用积分、金币等虚拟资产抵扣;多次付款(例如预付款等)。

相关业务模型:交易订单、商品、优惠、优惠券、积分、金币等。 


2)    付款

为了方便用户购买,很多时候需要支持多种支付方式,例如:支付宝、微信、银联等。

相关业务模型:支付订单


3)    发货与配送

对于拥有成千上万SKU的大商家而言,他们拥有自己的仓库,这些仓库也可能分布在不同的城市,所以他们需要能够管理所有的货物,直到他们的详细信息,选择一个最为经济、快捷的仓库给买家发货。

对于仅拥有几十上百SKU的小商家而言,他们对自己有多少货物心中有数,不需要仓库,甚至直接从家里发货。

发货是一个复杂的过程,如果用户购买了多件,可能会打包一起发送给买家,也可能将一个大件物品拆成多个物流单发给买家;配送的过程也很复杂,涉及物流订单的集散以及派送过程。不过幸运的是很多情况下这些都不需要我们自己实现,直接用第三方的物流服务,我们尽关心物流信息即可。

相关业务模型:商品、商品SKU、货物


4)    收货

对于用户而言,收货仅仅是点击一个“确认收货”按钮而已,很简单,就不多说了。

相关业务模型:交易订单


5)    退款退货

常见的处理流程是:buyer提交退款/退货单,seller确认,如果一切顺利,seller同意退款/退货,buyer将货物发回并将相关物流单号等信息备注好即可。如果seller不同意产生纠纷,这时可能需要平台来做一个裁决。

相关业务模型:退款/退货单、纠纷信息


6)    收货退款

seller收到货物以后,更新退款/退货单信息,系统将钱原路退回即可(绝大多数情况下都是原路退回)。

相关业务模型:交易订单、支付订单


7)    评价

buyer为此次交易进行评价,为其他买家提供参考。

相关业务模型:评价


8)    对账结算

对于平台而言,不但为买卖双方提供交易渠道,也承担了担保人的角色,防止违约事情的发生。一般而言都会有一个结算后期,例如过了退款退货期限,才给商家结算款项;或者每个月结算一次等等。

对于自营的平台而言,这个过程可能会稍有不同。

相关业务模型:交易订单、支付订单、结算单


三 系统架构

从业务域的分析可以看到,完整的交易涉及了buyer、seller、平台、物流等多方;涉及多个正向、异常流程有;另外不同类型的商品的交易流程也会有所区别。综合这些信息来看将所有的业务放在同一个系统中,必然造成系统的臃肿,很容易造成耦合严重,功能相互影响,不方便扩展,优化困难等问题。

如果过多设计系统,系统拆分的过于细小,必然对开发速度、维护成本产生影响。

那么问题来了,我们应该如何划分系统?

1.   系统架构原则

这里仅仅讨论业务架构中几个常见的原则,为讲述讨论交易系统业务域划分做准备。

1)    没有最好的设计,只有最适合的设计。

业务发展的不确定性高,流量小或者中短期内达不到非常高的量级时,越是能以最小的成本达成业务需求的设计,越是优秀的设计。举个例子:如果开发成本只需要一两周,能满足半年到一年的设计很多时候比一个开发成本需要三四个月,能够满足5年需求的系统更加适合。且不说业务一定能发展的好,后者一定能排上用场;长的开发周期必然会拖累业务的快速发展,这是逼着业务拿刀过来砍人了(开个玩笑)。

产品应该小步快跑,系统设计与开发也应该是小而快,避免过度设计。

2)    架构要与业务水平、技术人员的水平匹配。

以淘宝、京东的架构来为一个初创公司架构系统显然是错误的。一来团队人员数量、质量跟不上这些公司;二来请求的流量、业务复杂性不如他们。如果强行使用他们的架构会严重降低开发速度,增加开发、联调、测试、发布等环节的成本,浪费服务器资源、增加维护成本等等。

3)    要能够水平扩展

上面建议不要过度设计,但是如果业务飞速发展,如何能够满足满足业务的需要,让业务不受技术的拖累?系统能够水平扩展是一个非常好的选择,通过增加服务器来为重新优化设计系统提供缓冲时间。

现在有很多开源软件提供了不少方便水平扩展的技术和中间件,例如dubbo、zookeeper、MQ、缓存等。不过在我们的系统中也应该做到以下几点,以方便简单的水平扩展:

    尽可能降低db层的压力,因为增加业务服务器比增加DB实例要简单方便很多。

    服务器无状态,或者自动管理状态。做到这样部署1台服务器和部署10台开发成本几乎一样。

    尽可能使用分布式技术。例如:如果锁定资源,要尽可能使用分布式技术,而不要使用单机技术,否则增加服务器就可能产生不可预知的问题。

4)    要解耦、要易扩展

解耦、易扩展是为了降低维护成本,降低不同业务之间相互影响,提升系统可靠性、可用性的一种手段。面对业务发展不确定性,保证系统具有这两个品质,可以为以后流量快速增长、业务转型、多业务接入打下一个良好的技术。

2.   交易系统的责任与追求

1)    交易系统业务域

关注交易的核心流程,负责订单数据以及状态流转;兼容上层多样性的业务。

一般而言各种不同类型业务的交易流程都会有一定的差异性,此时应该仔细思考交易系统和上层业务的边界,让各个业务系统负责自己的业务领域中的个性化需求,将具有公用性的逻辑沉淀到公共的交易系统中。

简单来说就是对交易模型进行抽象,并定义一个抽象的交易流程出来,不同类型的交易在抽象的交易流程上进行扩展并添加个性化逻辑。

2)    交易系统业务目标

支持多种业务的交易流程;方便、快捷的接入新的业务。

技术是为了解决问题而存在,在公司中技术为业务服务,快速响应业务需求是对业务最大的支持;同样的强大的技术也为业务提供了更多的玩法和趣味性。

3)    支付系统技术目标

低耦合、高可用、易扩展。

高耦合对于系统维护而言是一个灾难;对业务来说会严重拖慢业务的发展,也会对业务的稳定性产生不利的影响。系统应该具有较高的鲁棒性,即便出现了部分服务故障,也应该能够继续提供服务。业务一般不会一成不变,可能快速发展,并发极具增长,可能因为陷入困境而寻求专项,所以系统要能够便于扩展。

 

3.   交易系统架构

站在交易系统的角度来看,交易系统的架构如下图所示:

a41dbc741e2d609ff059f04930b9e089c8d0b1b1

说明:之前的一家公司同时做化妆品、旅游这些业务,所以这里我以这些业务为示例讲述。

此架构是根据交易中涉及的业务来划分的,根据实际的场景可以划分的更加细或者更加粗糙一些。

更细化的业务划分示例:如果公司的业务对运营有更多需求,那么优惠、优惠券系统可以进一步的拆分;若积分、金币的业务场景差异性较大也可以拆分成多个系统。

更粗化的业务划分示例:如果业务上不是非常关注仓储、物流,那么这一部分内容放在交易系统中也是可以接受的。

简单来总结一下就是:如果业务差别大、需求多、变化频繁,那么更加细力度的划分是非常合适的;如果需求少、基本没有变化的,为了满足业务快速发展简化业务逻辑,可以将他们合并在一个系统中(模块上最好还是分开),等未来业务上来了在拆分不迟。

 

4.   交易系统领域划分

1a2459d24d9aab0bd175ef453324091dd9502795

5.   交易系统结构

下图是以服务层次的角度来看交易系统的结构:

07bbe6cfb80b25c5c480ceb911db83e8a7e51d96

从上向下多为RPC同步调用;从下往上多为MQ消息,即事件。例如:支付成功后,将交易订单改为已支付;评价后,将交易订单状态改为已评价等等。

交易表现层和交易核心层可以合为一层,是否分开,主要看业务上是否有这个必要。例如:如果交易业务的场景复杂多样,每种交易业务的差异也比较大,这时可以将他们分开,这样在核心层提供细粒度的服务,表现层通过组合多个服务来对外提供服务。

上层业务可以直接关注交易核心层的消息,即图中1处的流程,当然也可以通过交易表现层来实现,只是会复杂一些。

 

6.   交易系统数据模型

38756fcb7c517d1b4d85c6a7b5818dfc334f6bfe

以上模型是希望将围绕交易的所有核心数据都记录下来,此模型支持任意对账需求。例如:交易使用总积分的对账可以通过交易订单和积分抵扣流水进行对账;总收入可以通过交易订单金额和支付订单金额进行对账。

另外,以上模型也可以进行进一步细分,具体可以参考推荐的一篇博客。

 

7.    一切都基于事件驱动

下面仅仅以创建订单和支付为例,描述基于事件驱动的微服务架构。更多内容请参考推荐的博客。

1)    下单

37b08a045ba8577e8bc809c4fc8f86d678f542d1

2)    下单补偿

此流程是为了解决分布式场景中rpc失败,而导致积分、优惠(券)误用,商品误减,当然如果业务上无相关要求,此流程可以忽略掉。

17bbd2a121ef789b86d58ef303a2df9c20d796b6

3)    支付

b09749e8aaef7c74e3e5dad5f2ae2c3210f6cf29

4)    交易达成

162c1dadaf3c52a6787f15b8d0638ea7a3de4de4

支付订单状态驱动交易订单状态修改

5)    个性化业务

b5685678e600e70325d8e049bc13b97d1e8f74f0

交易订单状态,驱动上层业务个性化需求。

6)    总结

基于事件驱动的架构是一种非常好的解决复杂业务的手段。其核心思想是交易系统负责交易核心数据以及状态流转,将状态流转作为事件暴露出去,关心此事件的业务系统监听消息,完成个性化业务诉求。

当然另一个好处就是解耦,可以认为MQ就是为解耦而生的。

8.   设计总结

完整的交易包括非常庞大的业务领域,所以在设计的时候应该首先梳理业务,清晰业务边界,根据公司当前的状况以及对未来业务发展的评估,将不同业务划分到不同的系统中;依托现实场景,抽取交易相关的核心要素,然后抽象出实体模型;沉淀公共部分为公共的服务;以数据模型作为基础,以事件作为推动整个流程流转。

 

四 高可用与高并发

目前有很多成熟的技术可以实现高可用和高并发。这里先简单讨论与上面的系统设计中直接涉及的几项技术。以后专门写一篇博客,再详细讲述高并发与高可用的技术。

1.   交易系统的高可用与高并发

1)    负载均衡

同步调用使用的Dubbo本身就支持负载均衡。异步使用的RocketMQ本身也支持负载均衡。

2)    异步并发与队列

通过RocketMQ实现。

3)    倒金字塔型的过滤模型

分层逐步过滤非法请求。例如营销活动中,先在h5层拦截用户的重复请求;上层应用根据活动拦截异常请求,以及重复参加活动的请求;保证最后达到交易系统的仅仅是合法的请求,并且尽可能让过来的请求都可以成功。

4)    隔离

常见的手段有:业务隔离、数据隔离、进程隔离/系统隔离、线程隔离、读写隔离动静分离、热点/爬虫隔离、资源隔离、故障隔离

5)    解耦

架构层面:架构中划分业务域、梳理业务边界、梳理系统的依赖关系其实就是在做系统解耦。

细节层面:通过MQ消息对系统、服务进行解耦。

6)    幂等

分布式开发中,凡是通过RPC进行写操作,或者需要重试的均需保证接口幂等。常见手段是:DB唯一键;写操作前先检查;分布式锁。幂等一般和防并发操作写一起使用。

7)    数据最终一致性

分布式场景下,因为存在诸多不确定因素,导致数据不一致,特别是网络不稳定,相关的服务不可用等。保证数据一致性的手段有:最终一致性,TCC、2PC(或3PC)。

根据之前公司的业务场景以及性能要求,我们都是采用RocketMQ实现最终一致性这种方案。具体可以参考:RocketMQ实践

2.   高可用与高并发技术

1)    高可用技术

隔离技术、限流技术、降级技术、负载均衡、容灾与备份、读写分离、监控、系统解耦等。

2)    高并发技术

动静分离、缓存、 异步并发、 扩容、 队列等


 

网友评论

登录后评论
0/500
评论
小飞哥1112
+ 关注