TOP100summit:【分享实录-猫眼电影】业务纵横捭阖背后的技术拆分与融合

王洋:猫眼电影商品业务线技术负责人、技术专家。主导了猫眼商品供应链和交易体系从0到1的建设,并在猫眼与美团拆分、与点评电影业务融合过程当中,从技术层面保障了商品业务的平稳切换,同时也是美团点评《领域驱动设计》课程的讲师。在加入猫眼电影以前,曾就任于蚂蚁金服,参与了阿里网商银行从0到1的建设,以及支付宝钱包、花呗等产品的研发。算法

导读:互联网电影行业在2016年经历了较大的变更,其中包括猫眼电影和原美团的拆分,以及猫眼电影和点评电影业务的融合。业务发生大的变化时,技术一般也会作出较大的重构,猫眼后台技术团队在整个拆分、融合的过程当中,对系统架构、领域模型进行了比较多的调整和思考,探索出一套成本和收益较为平衡的技术方案。本文将分享实践的具体过程、步骤和方法,但愿给后互联网时代,遭遇业务拆分和融合的技术团队提供一些参考案例。数据库

一.问题的提出架构

具备必定规模的互联网公司,一般会有不少的细分领域和垂直业务,为了提升效率,大部分公司都会采用平台化的思路:建设一套通用的基础平台,全部业务线基于这套基础平台搭建本身的业务和技术服务。这种作法一方面能够缩减人力成本,另外一方面也能够提升新业务的开发效率。猫眼的商品业务一开始为了快速发展,就采用了这种发展模式,将整个业务的交易都搭建在美团的团购体系之上,如图1所示:并发

从上图能够看出,商品业务彻底依赖于美团的商品、订单、支付、促销、劵服务,耦合性很是高。因为当时美团和猫眼是同一家公司,这种耦合性是能够接受的。但后来猫眼独立了,组织架构、业务规划出现了较大的不一样,这种耦合性就变成了商品业务后续发展的一大难题。app

基于独立发展的考虑,猫眼须要将商品业务从团购体系拆分出来,并和点评电影的商品业务融合在一块儿,组建一套新的业务和技术体系,用来支撑后续的业务发展。运维

通过大量的现状分析和调研以后,团队肯定了这次技术升级的目标:异步

● 产品需求不能中断。
● 最低的客户感知度。
● 新旧体系能够自由切换。
● 最低的试错成本。
● 持续分阶段交付、验证。微服务

电商体系从供应链到交易再到结算,复杂度已经很高,再加上业务切换、数据整合的时间,必然会是一场持久战。为了减小风险,让商务、财务等团队更好地配合咱们,技术团队必须分阶段产出,作线上验证。工具

肯定上述的5个目标以后,接下来咱们就要思考如何围绕这些目标设计总体的方案。组件化

二.技术拆分方案

首先,咱们来分析一下业务场景,图2是商品业务的简图:

从图2能够看出,整个业务能够被拆解为四个大的模块,这样咱们就粗略地肯定了团队的分工:供应链、交易、消费、消费后服务。肯定好团队的组成,接下来咱们须要对服务的重要性和优先级作一个明确的划分。分析的维度以下:

● 基础数据层面,如商家、用户、合同,这些是公司长期积累下的资源,短时间内不可能重建,因此这个层面的服务,尽可能复用之前的服务。
● 核心服务层面,供应链的核心是上单,交易的核心是商品、订单、支付、促销,消费的核心是物流、商品券和与之对应的网关服务,这些都是交易的主流程,必须重建。
● 财务层面,如对接商家的结算,以及反应业务运转状况的帐务,在公司拆分时,一般是须要独立核算的,因此这个层面的服务也必须重建。
● 非功能性服务,例如客服、售后,这些服务一般优先级不高,可是没有的话,会影响用户的体验,因此尽可能考虑复用之前的服务,后期再考虑重建。
通过上面的分析,咱们肯定了一期工程须要重建的服务。

2.1 拆分的前置方案

肯定了须要重建的服务以后,还不能急于开发,要提早思考若是全部的服务都已经有了,该如何作切换。须要考虑的事情有这么几点:

● 切换期间,商品如何售卖。

在前面咱们确立了“新旧体系可自由切换”的目标,因此在切换过程当中,须要保证商家和运营上一次单,就能够在美团、点评、猫眼三个体系中售卖,这样能够提升切换的灵活性,减小切换带来的交易损失。

● 版本问题。

前文已经提到,商品业务一开始是在团购之上搭建起来的,客户端调用的大部分接口都是美团团购的接口。最直观的作法是在团购接口中加上判断,将电影品类的交易请求导流到猫眼这边,这种作法速度快,且没有流量损失,但之后修改接口参数、扩展业务的负担比较重,可维护性比较差。

● 切换的方式和粒度。

为了达成“新旧体系可自由切换”和“最低试错成本”的目标,在切换过程当中,必然会处于一个新老并存的状态,因此咱们不能简单地替换接口,而要采用更灵活的切换方式和更细的切换粒度。

● 与猫眼现有业务的关系。

猫眼自己有一套选座交易,但受制于行业模型,暂时没法支撑商品交易。考虑到将来确定是须要融合的,因此须要提早考虑两套交易的关系。

2.1.1 上单双推

针对售卖问题,猫眼采用了“上单双推”的作法,如图3:

正常状况下,上单系统在确认商家提交的商品信息后,会将商品推送到商品中心。为了让商品在美团、点评、猫眼三个体系中售卖,猫眼须要作如下几步操做:

● 历史单迁移。

先从美团商品中心将当下能够售卖的商品同步到猫眼,保持对齐。

● 创建关系映射。

对于商家来讲,不管商品在几个体系中售卖,都是一个商品,在统计销量、结算时,都应该是一个商品,因此咱们须要将多个商品中心的商品关联起来。这个作起来比较简单,只要给猫眼的商品分配一个id,而后在商品数据中存下对方的id就能够了。

另外,为了区分两个体系的商品,咱们采用分段的策略来分配商品id,好比当下的美团商品最大id是X,那么猫眼的商品就采用2×X做为id的起始,而在美团商品id增加到2*X以前,咱们确定完成了切换,不用再考虑id序列统一的问题了。

● 商品双推,库存按比例分配。

猫眼上单系统确认商品信息后,将商品推送到美团、猫眼两个商品中心,并建立各自的库存,根据当下的交易比例分配库存量。因为美团、点评两个体系是通过融合的,因此只须要推送美团团购,点评就能够售卖了。

2.1.2 业务入口回收

解决了售卖问题以后,接下来咱们来考虑版本和切换方式的问题。

众所周知,移动App一旦发版就很难再改动代码了,因此切换完成后,老的版本很难支持现有的体系。但通过分析咱们发现,猫眼涉及的几个App,2~3个版本能够覆盖到90%以上的客户端,而核心 服务自建足够支撑3个版本以上的迭代,这样所有切换完成的时候,能够把老版本的流量损失降到5%之内(老版本的用户交易意愿有必定折损),这是一个能够接受的范围。

为了加快切换的速度,咱们须要在核心服务自建以前,先把交易和消费环节全部的业务入口,也就是客户端调用的接口所有替换成猫眼本身的接口,由猫眼来对接美团的服务,如图4所示:

在美团的服务之上,先创建一个业务流程层,给客户端提供交易和消费环节所须要的接口,而后由业务流程层转接美团团购的基础服务。例以下单操做,原先是直接调用美团订单的接口,如今由交易业务系统作转接,一旦猫眼的订单系统开发完成,只须要将美团订单服务替换成猫眼订单服务就能够实现无缝对接了。

2.1.3 切换方法和粒度

收回业务入口之后,接下来须要考虑切换的粒度。

目前有这么几个粒度:商品、影院、App、入口位置(场次页、支付页、取票机、搜索、推荐)。综合起来看,影院+入口位置是比较合理的粒度。

商品粒度太细,且数据是动态变化的,维护起来比较麻烦;App维度又太粗,一次性切换起来涉及的范围太大,且没法回滚;影院的粒度处于中间,数据变化小,流量也比较好控制,因此咱们采用了影院做为主要的切换粒度。

另外,因为商品业务自己的特色比较碎片化,入口众多,还得对接美团、点评的搜索、推荐等服务,因此将入口位置做为辅助的切换粒度。

切换以前,先给全部的展现入口分配固定的渠道号,如图5所示。支付页是渠道1,取票机是渠道3,客户端在请求后台数据时,须要带上渠道号;而后商品业务系统将查询逻辑抽象成处理器,例如猫眼支付页处理器对接猫眼的商品中心,而美团的支付页处理器对接美团的商品中心,公共流程如排序、最低价计算,能够抽象到父类中。

当一个查询请求到达商品业务系统后,由渠道分发控制器根据渠道号选择对应的处理器,同时,渠道分发控制器须要询问渠道切换服务的建议,看看是走团购体系仍是走猫眼体系。而咱们只须要在渠道切换服务内部维护一个走猫眼体系的影院+渠道列表,而后用配置推送服务动态更新,就能够实现影院+入口位置两个维度的自由切换了。

经过以上的办法,后台系统已经在商品展现层面实现了两个体系的自由切换,但后续的交易流程还有很长,须要客户端可以分辨后续该使用哪些接口,才能够走到正确的交易流程。图6是客户端须要配合作的改动:

客户端须要维护两套交易接口的列表,一套走美团,一套走猫眼。后台接口在返回商品数据时,会带上商品是否猫眼的标记,若是为true,则后续流程都使用猫眼的交易接口;若是为false,则都使用美团的交易接口。等到切换完成,后台返回的标记所有变成true,客户端也能够考虑删除这段逻辑,直接使用猫眼的接口列表。

2.1.4 统一id服务

最后,考虑商品交易和已有业务的关系。

交易的核心是订单,而猫眼内部已经存在一套选座订单了,但这二者的模型差别很大,没法复用,因此只能选择自建订单,在订单号层面作好统一,下降将来数据融合的复杂度。

统一订单id,就须要一个统计id服务,如图7所示。每一个交易业务在下单前,都从统一id服务获取订单号,而后再下单,这样能够保证整个公司的订单号分布在同一个递增序列下,下降促销、结算等系统融合的复杂度。

2.2 核心服务自建

完成了前置方案的设计,接下来要分析交易须要哪些核心服务,下面是商品业务的行为分析图:

从上图中能够看出,整个交易过程能够简单的划分为三个阶段:交易前(商品为核心)、交易中(订单为核心)、交易后(即消费过程,商品券为核心)。下面详细分析每一个阶段的核心模型该如何设计。

2.2.1 商品输出模型

根据商品的做用,咱们能够将商品信息的存在形式分红三个阶段:编辑阶段、使用阶段、业务聚合阶段。如下是这三个阶段的说明:

● 编辑阶段,即还未成形的商品。

这个阶段以上单流程为核心,维护商品的写模型,因此须要重点关注商品的增删改操做,并作好审核机制和操做记录。这个阶段的模型主要维护在上单系统里边。

● 使用阶段,即经过审核,容许售卖的商品。

这个阶段维护的是商品的基础信息,一部分信息是只读的,例如商品标题、价格、所属的门店等;另一部分是可变的,例如库存量、销量、商品状态等。使用阶段的模型主要维护在商品中内心边。

● 业务聚合阶段,即整合其它信息之后的商品。

这个阶段维护的是商品的读模型,不能改变商品的任何信息,例如商品列表是聚合了多个商品信息,商品详情则是聚合了商品基础信息和促销信息。当外部系统,例如搜索等服务须要接入商品体系的时候,都应该输出业务聚合阶段的商品。这个阶段的模型主要维护在商品业务里边。

定义好商品的三个阶段之后,就能够根据每一个系统使用商品的方式来组织系统的关系,获得图9所展现的输出模型。

2.2.2 订单处理模型

订单是交易过程当中最重要的模型之一,也是最容易和业务耦合太重的模块。因此在设计订单模型的时候,须要重点考虑如何让订单和业务流程分离,只关注订单的基本信息和状态流转。考虑点主要有如下几点:

● 命令模型和查询操做须要分开,即CQRS。

例以下单和查询订单详情两个操做,前者是交易的主流程,会写入订单的信息,然后者不会改变订单的任何信息,只须要查询到订单便可。另外,下单重视的是业务流程,核心指标是稳定性和准确性,而查询订单详情重视的是数据聚合,核心指标是完整性和用户体验。

● 业务流程和订单处理过程须要分离。

例以下单操做可能会分为好几个步骤:判断商品是否可售、计算商品的价格、锁库存、写订单数据等。这些步骤是业务流程,订单不该该关心。并且每一个业务的交易流程可能会不同,因此须要一个灵活性更高的办法来处理交易流程。

考虑以上两个问题后,咱们设计出了订单处理模型,如图10所示。

首先得开发一个任务处理引擎,负责处理业务流程中的单个任务,例如锁库存、生成商品券、推送订单信息等等。每个任务都对应一条数据库记录,用来讲明要使用哪一个处理器、用到的数据该从哪里获取,以及步骤完成以后该怎么办,记录之间也会使用编号链接起来,用来处理优先级和依赖关系。

接单服务负责将不一样业务的下单流程拆解成一个个子任务,并肯定好任务之间的优先级和依赖关系,进行简单的编排,而后写入到任务引擎的数据库中,而任务引擎则负责捞取这些任务,分析并执行已经编排过的任务。这种方式的好处在于业务流程被拆得很细,不一样业务之间能够重用一些任务处理步骤,当一个新的交易业务接入的时候,只须要添加对应的子任务处理器,而后在接单系统中配置编排的规则,便可快速支持。

如图10所示,咱们将订单的写模型和查模型分开,让增删改三个操做都走订单核心系统的写模型,而用户查询操做则走订单查询系统的查模型。每次订单信息有变化的时候,订单核心会通知任务引擎,由任务引擎负责更新查模型。这期间会有时间上的延迟,因此订单查询维护的查模型只能给用户端展现需求使用,而退款过程当中查询订单状态则必须走订单核心的写模型,由于写模型的状态是实时的。

用户成功支付订单之后,订单核心会收到支付成功消息,而后将不一样类型的订单拆分,并挨个通知任务引擎,执行支付成功后的业务流程,例如生成商品券、推送订单信息到美团订单列表等。

2.2.3 商品券与结算模型

商品券和物流是消费过程当中的核心模型,而结算恰好要的就是消费维度的数据,因此这二者的设计紧密相关。因为商品券和物流比较相似,因此本文只介绍商品券的模型。
商品券的本质是一串数字,用来做为兑换服务的凭证。它的特色:

● 一是要足够乱,不能让你随便输入一个数字就可使用;
● 二是不能重复,不然没法分清对应的是哪一个服务。

在数据操做上,商品券须要支持生成、验证、撤销等操做。
通过以上分析,咱们设计出了商品券和结算的模型,如图11:

为了足够乱,系统须要一个随机数生成的模块,同时为了避免重复,须要为随机数创建一个防冲突表,每次生成完随机数,都须要到防冲突表里查一下是否有使用过。因为随机数是有限的,生成的码越多,冲突的几率就越高,对并发度会有必定的影响。为了优化这个问题,咱们采用了异步生成的方式:先预生成必定数量的劵码,并添加到一个可用劵码的队列中,在不一样的并发数下,只要调整队列的容量和预生成速度就能够支持了。

当用户经过pos机等设备验证券码的时候,商品券会发消息给结算系统,结算系统会写一条流水数据到数据库中,并按照结算周期聚合到一块儿造成付款计划。结算系统也会天天扫描合同中约定的结算周期,触发打款操做。

2.3 线上线下切换

在前文介绍的前置方案里,咱们已经提早将切换点埋入到了客户端中,当交易模型搭建起来时,线上实际已经有大量的客户端支持在两个体系切换了。但此时,咱们还不能着急将全部的商家都切换到新体系,须要考虑更多的问题:

● 旧体系已有的业务,在新体系是否都已经支持。例如促销、优惠券,必须在业务对齐的状况下才能切换,不然会干扰到商家的正常运营活动。
● 商家结算的模式是否支持切换。在拆分过程当中,结算、财务方面的数据是惟一不能迁移的数据,任何的变化都须要两个公司财务之间核算清楚才能执行。因此在切换以前,须要根据结算的模式,将商家作好分类,优先将结算方式简单的商家切换到新体系,用于验证线上服务的正确性和切换方案的合理性。
● 交易过程当中是否依赖第三方系统。例如猫眼在交易后的过程当中,依赖了影院的第三方券系统,致使了这部分影院必须在对接完依赖的第三系统以后,才能够切换。
分析完上述三个因素,肯定好能够切换的商家列表以后,就能够开始和商务一块儿推动线上线下的切换了。切换的过程当中,须要注意线下的切换一般比线上要缓慢,因此要预先启动线下的切换,并让商务团队给商家作好培训。

三.技术融合方案

通过技术拆分,猫眼实际拥有了一套完整的商品供应链和交易体系,而此时点评的商品业务也有一套本身的供应链和交易。为了下降从此的维护成本,咱们必须将点评的商品业务适配到猫眼的这套供应链和交易体系之上。

供应链层面的解决方案和拆分的方案相似,这里再也不详述,重点说说交易层面的适配和融合办法。设计融合技术方案的时候,须要重点考虑这么几个问题:

● 客户端调用接口的迁移问题。点评客户端以前对接的都是点评的业务服务,须要替换成猫眼的业务服务。
● 交易流程衔接以及页面跳转的问题。融合以后,核心的如订单、支付、券消费确定得走猫眼的交易体系,因此整个交易的页面和跳转都应该使用猫眼的页面。
● 已经有的数据整合问题。在融合以前,点评已经积累了大量的商品订单和券数据,这部分数据须要和猫眼的数据进行整合,才能知足用户和商家的查询需求。

3.1 业务入口适配

针对客户端调用接口的问题,解决思路和拆分的方案差很少,也是提早创建业务层,将客户端使用的接口都回收到业务系统,而后再适配到猫眼的业务服务,如图12所示。

为了尽可能不维护两套业务系统,猫眼在融合一期工程的时候先采用了简单的适配,目的是将业务入口先牵引到猫眼的交易体系,而后在后续的开发中再让点评客户端直接对接猫眼的业务系统,逐步取代点评的适配层,等到须要适配的版本愈来愈少的时候,就能够废弃掉这个适配层了。

3.2 交易过程使用触屏版

交易流程的衔接和跳转是个比较棘手的问题,一是猫眼之前没有在点评客户端作过开发,为了融合单作一套native交易页面的代价较高;二是从此在作功能迭代的时候,要适配的端太多,会拖慢产品迭代的速度。综合考虑了流量、体验和团队多方面的因素以后,猫眼决定使用触屏版来解决这个问题。

商品交易有一个特色,即大部分的下单操做都会先通过商品详情页,因此只要从商品详情页开始,作一套触屏版页面,就能够将交易流程都引导到猫眼的页面了。

然而商品的展现一般比较碎片化,可能会有搜索、推荐、商品列表、猜你喜欢等各类入口,因此进入交易的第一步就是尽量的让展现入口都跳转到触屏版的商品详情页,而后继续下单、支付,再跳转到触屏版的结果页。订单成功以后,猫眼再将本身的订单数据 推送到点评的订单中心,同时将订单详情页的跳转设置成触屏版。一旦用户点击订单列表,就又回到了猫眼可控的范围内,后续的退款、消费、客服就走回到猫眼的交易体系,具体的作法如图13所示。

整个过程当中,可能会遇到一些其它的问题,例如跳转登陆:点评客户端登录的是点评帐号,而猫眼的触屏版登录的是猫眼帐号,因此这个作法还依赖于帐号的融合。在跳转收银台的时候也须要当心谨慎,须要点评收银台和猫眼收银台采用一样的验证方式和解析规则,不然极容易出现金额错误,或者没法支付的状况。这些也是触屏版须要考虑的问题。

使用触屏版的前提是:交易流程必须通过商品详情页,假如交易流程不通过商品详情页的话,就必须对多个业务入口进行适配,但跳转到收银台以后的流程,仍然是能够复用的。

3.3 数据整合思路

数据整合是技术融合中最繁琐的部分,作法一般有三种:

● 数据层面不作整合,在代码层面区分该走哪一个数据源。这个方法的优点在于数据可不作改动,但须要维护两套数据源,成本较高。
● 数据层面创建映射关系,而后经过转换层将数据转换成业务方须要的模型。这个方法的改动成本比较可控,能够快速实现两个体系的互通。
● 数据层面作完全的整合,将两方的数据迁移到一个数据源中。这个方法的优点是只保留一套数据模型,后期可维护性高,但整合的难度大,须要重点处理差别数据。

猫眼和点评数据的整合过程当中,主要之后两种方法为主,如图14所示:

查询数据一般使用的都是id,而咱们能够简单的将数据id分为两类:一类是不能变化的,例如影院id;一类是能够变化的,例如订单id。

对于影院id,猫眼和点评都有本身的一套序列,并且这两套id都依附在各自的商家体系上,不能轻易统一块儿来,因此只能经过创建映射关系的方式来实现互通。图14中左半部分的示例就是解决数据id不能改变的场景:

先将点评的影院id和猫眼的影院id创建映射关系,例如猫眼的影院id=1和点评的影院id=2,可能指向同一家影院(只是举例使用,不保证必定是对应关系)。而猫眼app和点评app依然使用以前的id,只是在查询数据的时候,会先通过数据转换层,由数据转换分析映射关系,拿到统一以后的影院信息。

对于订单id,用户一般不会手动记录订单id是多少,彻底依靠后台返回,这时候就能够将点评的订单数据按照猫眼的格式,迁移到猫眼的数据库中,并将id转换成猫眼序列的id,字段若是不一样的话,可使用扩展字段或者差别表作一层兼容。

图14的右半部分描述 的就是这种作法:用户在查询订单列表的时候,返回的是猫眼的订单id,那么进入到详情的时候天然就会查询猫眼的订单数据,这样就实现了数据整合。

须要注意的是:修改订单id的时候,一般须要修改全部和订单相关的数据,例如促销、商品券等系统,都是以订单id为区分依据的,这就须要同时改动全部受牵连的数据,须要当心谨慎地去推动。

4、案例启示和教训

技术拆分和融合的过程在猫眼内部持续将近半年时间,期间遇到了很多困难,对系统架构和模型也进行了较多的思考,如下是从案例中得到的启示:

● 在大公司作垂直业务时,若是要复用平台的服务,最好在客户端和平台服务之间创建业务层,作一层服务转接,这样能够为服务的替换提供更好的灵活性。
● 在设计系统模型时,尽可能让业务入口渠道化、处理过程组件化,这样不只能够提升系统的横向扩展性,并且也能够对每一个入口作更精细的把控
● 不一样业务在快速发展时,能够有本身的核心服务,但必须使用统一的id生成策略,保证模型的主要id属于同一个递增序列,这样能够为之后的融合,或者平台化减小数据整合的复杂度。
● 数据模型层面,尽可能将命令模型和查询模型分开,一方面能够将主流程和数据展现操做完全分开;一方面也能够下降数据操做的复杂性。
● 系统的流量控制和切换粒度要足够精细,这样能够提升应对风险的能力。

也从本案例中积累了一些教训:

● 设计技术拆分和融合方案时,须要全面考虑非技术因素的影响,好比结算、财务,数据既不能迁移,也不能修改,此时财务的结论颇有可能会影响总体的切换方案和模式设计。
● 线下的切换要提早进行,以便尽早收集到业务一线的反馈,能够并行的去修复问题,这样才能保证在线上开始切换的时候,不被拖慢进度。

5、总结和感谢

技术拆分和融合是一个庞大的工程,涉及的技术点比较多,因为篇幅有限,本文只是介绍了总体的设计方案,但愿给行业中遭遇相同问题的工程师们提供一个参考案例。

最后,在此感谢全部参与本次技术拆分和融合的技术、产品、运营和商务、财务团队全部的小伙伴,以及美团点评热心帮助的同事们。有了你们的紧密协做,才能在有限的时间里,完成如此复杂的技术升级。

11月9-12日,北京国家会议中心,第六届TOP100全球软件案例研究峰会,美团外卖算法架构师郝井华将分享《美团配送智能调度系统演进》;美团点评酒旅质量团队工具链负责人王鹏将分享《微服务架构下的自动化测试和持续集成工具链实践》。

TOP100全球软件案例研究峰会已举办六届,甄选全球软件研发优秀案例,每一年参会者达2000人次。包含产品、团队、架构、运维、大数据、人工智能等多个技术专场,现场学习谷歌、微软、腾讯、阿里、百度等一线互联网企业的最新研发实践。大会开幕式单天体验票申请入口

相关文章
相关标签/搜索