概述
携程商旅是一站式互联网差旅服务平台,为客户提供差旅管控、预订、出行、结算、成本、风控等服务的在线TMC(Travel Management Companies)。主要产线有:机票、酒店、火车票、打车、接送机、包车、租车、汽车票等。携程商旅订单系统针对B端客户定制化需求多样性,商旅产线丰富性,TMC业务与产品业务结合的复杂性等,对订单系统架构进行了优化。
一、背景介绍
订单系统作为入口,承上启下,涵盖了订单生命周期中所有的流程管理、TMC管控、创单中心、费用中心、履约中心、服务中心、聚合中心以及投诉理赔管理等。订单打通用户、商家、产品、库存、订后等关键业务,是驱动交易全流程运转的核心。
订单系统具备的能力,可以按照下面两个维度和多个角度进行切入拆解:
- 客户维度
员工视角:预定、公账垫付、个人支付、行程管理、退改服务、物流跟踪等;
财务视角:成本中心、交易流水、费用明细、账单报表、报销凭证等;
审计视角:审批授权、差旅管控、数据合规、政策合规、风控、反作弊等。
- 平台维度
客户实施视角:账户配置快照、订单聚合服务、API对接等;
供应商视角:商家拆单、订单状态管理、费用结算、售后管理等。
携程商旅订单系统在早期为了快速满足业务需求,产线为纯纵向独立模式,在业务的快速上线、风险隔离,有效地降低产品之间的耦合性作用明显。随着业务的快速发展、产品丰富度增加、产品之间业务关联程度深化、客户的定制化需求增多和创新型产品快速上线,当前系统架构出现了单一臃肿、耦合严重、功能重复、流程不统一、监控和运维弱等各种问题。
- 无统一的流程引擎,不能以灵活、可配置的方式支持B端客户快速增长的定制化、碎片化需求;
- 无统一的编排服务,导致子系统之间高度耦合、相互调用、边界不清晰;
- 多产线纵向模式、流程不统一、相似功能重复开发,不能快速的支持业务迭代上线;
- 多产线的订单数据无统一抽象、设计、聚合;接入端学习成本高、接入工作量大;
- 实时场景 (online) 和非实时场景 (offline) 耦合、不能有效隔离和保护核心资源,降低了系统可靠性;
- 缺乏有效的自动化补偿机制、监控体系、数据埋点,不能满足B端客户越来越严苛的数据合规要求。
2.2 流程设计 – 产线多、共性小
从多产线中抽取出共性(去重复、标准化),针对B端系统所具有的定制化、碎片化、特定性等需求,提供通用、统一的标准化流程方案。在标准化流程的基础上再结合订单系统特有的订单状态、订单事件、票号状态等,抽象出流程引擎,实现可配置、可扩展的标准化流程,从而达到化繁为简的效果。
2.3 快照设计 – 管控粒度细、维度多
差旅管控信息(账户配置、支付账号、审批授权、差旅标准、政策执行人等)作为差旅业务的基础信息,对其任何的改动都至关重要,一方面把每次的更改记录都保存下来。另一方面在每次交易订单的各个场景,需要将当时差旅管控信息持久化。以此作为各个子系统交易和运行的基础服务实现统一收口,同时以便问题的排查、处理投诉、维权、溯源等。
三、架构演进
Order Consolidation Service
3.2 Order Message – 客户端减负
设计API和服务时通常考虑较多的是API如何设计、交互、传参、client需要遵循的各种规则,较少的考虑client可以不做什么,client在享受服务的同时应该可以不做一切可以不做的事情。传统上消息发送服务设计为提供不同消息的发送接口,由各客户端根据各自的业务流程处理指定模板、类型、动态内容等调用对应的接口, 这个看起来是符合高内聚、低耦合的通用设计原则的。
原流程发送一个消息需要client端调用多个数据源查询数据、各种逻辑判断、消息类型、发送场景、模板处理等。新的设计将各个消息抽象为产线,场景模式对应一套配置和一套数据源API(统一为key-value输出),注册在消息中心,类似网卡插入主板后,需要安装驱动程序实现可插拔的方式大幅减少client端的工作,client只需要传一个场景即可实现一系列消息的发送。根据实际的业务场景,需要根据下面6种场景的排列组合,触发一个或多个消息的发送。
- 发送场景:创单、支付、确认客户、出行、成交等。
- 发送模板:支付类型、订单处理阶段、订单状态等。
- 发送语言:中文简体、中文繁体、英文、日文、韩文等。
- 发送类型:短信、邮件、微信、企业消息、站内信、手工操作等
- 收 件 人: 联系人、预订人、出行人、授权人。
- 数据来源:订单数据、成本中心子系统、审批子系统、账户配置子系统,消息附件等
Order Conductor
3.4 Order Fulfillment – B端场景
B端用户需求与传统的企业级软件有非常多的相似点,定制化和多样性是最为显著的共同点。商旅B端客户即使是基本的功能:支付流程、发单方式、管控流程、通知内容等都有显著的差异。以订单系统酒店产线举例,下面的订单属性和订单状态各个值排列组合出50种以上需要处理的流程,这仅是酒店一条产线。
订单属性:订单类型、授权顺序、支付方式、垫资方式、配置流程、国际国内、三方协议等;
订单状态:已提交、未提交、授权通过、授权拒绝、已支付、已出票、已取消、确认客户等;
不仅微服务之间需要统一调度和流程配置,而对于每个应用或每个服务同样如此。订单系统仅通过工作流驱动并不能满足要求,其最为重要的属性就是订单状态、订单事件等触发和驱动订单系统的流转。通过开发基于订单状态、订单事件结合工作流开发流程引擎达到可配置、可扩展、易维护的目的,而又避免引入较笨重的开源工作流引擎达到“够用即可”:
- 有状态、可重试、支持幂等,
- 任务持久化、可配置、可扩展、易维护,
- 基于状态、事件的统一处理流程;
状态驱动+流程引擎
四、论述与总结
什么是好的设计?
- 一个好的设计不是还能增加什么,而是不能再减少什么。
- 一个好的设计不是客户端需要做什么,而是可以不做什么。
- 一个好的设计是自动化一切可以自动化的东西。
- 一个好的设计是标准化一切可以标准化的流程。
什么应该横向?什么应该纵向?
什么应该纵向? 业务上共性少,差异大,对于客户需求需要快速响应,业务上需要快速试点和产品创新,正如图第一象限业务层展示的特点:特殊性,可变性。所以业务层在系统上应该纵向,隔离,但是在流程上标准化,可配置化,确保其灵活快速响应,尽可能少的涉及具体实现。
什么应该横向? 高确定性、高通用性功能应该横过来供不同的团队和子系统共享,作为各个产线子系统的基础,同时也是支持业务在已有系统上快速上线,创新,试点的平台。
当业务需要快速的上线和需要速度运行,快速推向市场的时候,我们应该让业务、产线分开快跑,应该把业务变成纵向的,独立成建制的往前快速推进,摧枯拉朽,策马狂奔。随着单量的增长和业务的延伸,尤其各产线趋同功能变多,定制化需求和创新性需求增多,合规性性要求越来越严格,系统就暴露出大量问题:大量低水平重复建设,重复开发,效率低下,运维困难,任何新功能,新产品上线都需要从轮子开始建造。当我们需要效率、要积累、要沉淀的时候,尤其需要在已有系统上快速创新、试点新的产品时候,就非常明显要把有些东西横过来,从整体上规划和设计,让整个系统架构统一,流程统一成支撑体系包括技术沉淀,子系统中台化演进让其能够有办法共享给其他子系统和团队。
什么叫中台,为什么需要它?中台被过度神化过,也被极端的污名化。中台并无对错,主要取决于设计与边界。其被诟病主要原因:
1)圈地运动:什么都能做,什么都可以做,基于不能重复建设的原则各client被强制要求接入。基于原则而实际上是无原则的开发模式,导致系统臃肿、边界不清晰、耦合严重,不能通用而被通用只能通过给client制定各种条条框框和特殊定义来约束系统之间的交互、接入成本和沟通成本高,反映不够灵活,对于创新型的业务不能快速的支持,需要反复的沟通和规则制定,不仅没有享受到便利,反而成为了负担。是一种明显的山头主义,势力范围的划分。
2)代理式中台: 高举高内聚、低耦合的伟大旗帜,这也不能做,那也不能做,将client视为负担而非流量。client需学习各种接入规则和传参契约,接入成本高和使用复杂,不同渠道稍有逻辑不一致需要client 自行处理,某种意义上说仅起到转发的作用。中台实际上是一个横向策略。如果你要速度,要快速,要机动灵活,一定是这根杆子从上到下,都是一个人或一个团队负责,这是最快的。而如果client 需要感知各种流程,等于是逻辑分散,没有做到真正的抽象和下沉。业务中台需从整体上设计基于配置化编程满足不同渠道的需求,而又不打破低耦合的原则,而非仅仅是个代理,是个类似基础架构的网关。
3)资源垄断:垄断了资源输出和对外交互,client除了接入无其他选择。同时又受制于团队体量,团队话语权,ROI等各种因素得不到排期或列为低优先级任务。