滴滴的出行交易形态大致可分为预估、发单、抢单成功、司机到达、开始计费、实时计费、结束计费、发起收款、支付等环节。价格作为其中的核心属性,贯穿着整个订单流程,而计价要解决的就是和价格相关的问题。
对于出行场景而言,价格是影响用户决策的最重要因素之一,计价给用户提供的核心价值就是准确的价格计算。
出行服务和普通商品在价格上最大的不同就在于二者定价方式的不同,用户在电商平台买一件衣服或者在线下实体店买一件商品亦或是去餐厅吃一次午餐,用户应付的都是相对固定的价格,虽然价格会有波动但标准商品的定价方式决定了其在一段时间中是固定不变的,但出行服务不一样,不管是传统的出租车还是如今的网约车,每次乘客出行都可以说是一次定制化的服务过程,起终点的不同、行车路线的拥堵情况、行车的时长、等等因素都可能影响最后的出行费用。
对于用户而言,计价系统最重要的任务就是把价格算明白。目前在发单时,用户输入起终点后,平台根据实时路况、预估行驶时长等因素综合估算出来了一个预估价,供乘客作为出行参考。预估价不同等于实时价格,其主要目的是方便用户做决定。在这一环节,计价系统都竭力保障用户看到的是一个能反映此次行程所有影响因素的准确价格。此外,在行程中的实时计费和行程结束后的账单明细,计价系统都在用户提供高效、稳定、准确的价格计算服务。
供需关系也会影响网约车的价格。面对季节性的供需变化,平台网约车也已经开始尝试淡旺季调价,在出行旺季适度涨价,鼓励司机多出车接单,帮助乘客更快叫到车,同时提升司机收入;在出行淡季适度降价,通过优惠吸引更多乘客打车,保障司机接单量从而稳定收入减少波动,让用户和司机达成有效的撮合。在这个过程中,计价系统为业务方提供了各种价格相关的能力,包括但不限于定价(城市、围栏、场景)、开放计价、价格权益等能力,从价格定义、定价调整、价格活动运营、价格计算、价格感知到最后价格的异议复盘等提供一站式价格服务。
除了提供这些具体的能力之外,计价作为滴滴平台的中台服务,承载了网约车、 国际化、单车、共享汽车、包车、国际化顺风车等多业务线、多产品形态的价格服务,通过中台能力复用,为公司的降本增效添一份力。
宏观上看,整个计价系统是由多个子模块组成的分布式系统,对外提供 HTTP 接口接入,并提供封装好的 SDK 方便业务方高效对接,内部模块通信则使用更高效的 thrift 协议进行通信,与此同时计价还依赖滴滴平台提供的各类服务如地图、围栏、订单等等,数据层则使用 codis、ddmq(自研消息队列已开源)、fusion(自研 NewSQL)、MySQL、ES、HDFS 等组件。整个系统架构如下图所示:
从上往下来看,各模块提供的功能如下:
InRouter 网关是滴滴平台的统一网关入口,通用的网关功能无需多言,对于计价而言比较特殊的是其提供了基于司机 id 的一致性 hash,一致性 hash 会将同一司机的请求打到同一台机器,在整个系统内部,我们对大量数据做了内存级的缓存,用于提效和降级兜底。
Application 层是计价的基础计价模块,承担计价主流程,负责对外提供服务,包括预估价格计算、配置搜索查找、行程轨迹计算、费用聚合等核心能力。该模块是整个在线系统的主要出入口,模块本身无状态可以进行无限水平扩展,在高峰期可以通过滴滴云平台完成分钟级别的扩容。
config 模块是一个高度灵活抽象的配置平台。其配置包含多种多样,包括城市、围栏、场景、开放化计价等定价功能模块,同时还包含价格权益、i18n 多国语言、费用项定义等模块,配置平台将不同的业务配置抽象成一个个模块,一个模块对应一个配置列表,每个配置都包含的所见即所得的编辑组件,如下拉框、文本框、日期选择等组件,这些组件可以进行自助化定制、编排、组合以满足不同配置要求。同时通过 RBAC 权限校验机制进行权限隔离,确保了敏感数据的权限收敛。通过灵活抽象,做到了与业务完全解耦,成为一个通用化的配置平台。其底层则使用滴滴平台及的配置服务 Apollo 来连接线上环境,从运营更改配置到线上生效可以做到分钟级的速度。Apollo 是一个适用于多种场景的 A/B 实验与灰度发布、配置同步的平台,通过科学合理的 AB 实验数据辅助业务决策与效果分析,利用简单易用的灰度、配置功能提升开发效率,降低上线风险。
module 层是滴滴内部的基础组件,包含服务发现、分布式配置中心,metric&trace&log、rpc 通信框架等基础服务组件。
service layer 服务层是包含十余种服务的依赖层,计价将一些比较独立的功能拆分成单独的子模块,一方面在功能和业务上进行解耦以降低基础计价的复杂度,一方面提高系统稳定性和迭代效率。下面介绍其中一些服务模块:
ETA 是地图平台提供的路径规划服务,为计价提供预估计算时的路线规划能力;Cratos 是开放化计价服务,通过热插拔的插件、接口回调等机制,为业务方提供干预账单的能力。Dealer 则是账单渲染模块,承担账单明细、计价规则等费用感知的页面渲染。Fence 服务是滴滴内部的地理围栏服务,通过查询 Fence 服务,可以知道一个坐标点是否在一个特定的电子围栏中。
接下来介绍下数据层。
整个在线系统底层的存储依赖为 Codis 和 fusion;Codis 是一个分布式 Redis 解决方案。Fusion 则是滴滴自研的分布式 NewSQL 数据库,完全支持 Redis 协议,部分支持 MySQL 协议,并提供 PB 级别持久化、跨机房多活、FastLoad 导数据、单机跨行事务、binlog 吐出等高级功能。系统主要依赖 Codis 进行在线热数据的操作,如行程中的订单信息,其中包含像当前位置经纬度,累积走过的时长、里程等关键信息,这些信息会在每一次坐标点上报之后进行更新,计算出当前实时账单发送给司乘两侧以感知当前的实时费用情况。Codis 的部署为双机房双主互相同步,通过前面介绍的一致性 hash 机制,可以确保同一个司机的请求只会在一个机房,同时因为双机房实时互相同步,因此一旦某个机房出现问题,另一个机房都包含系统的全部数据,出现这类故障之后,线上故障检测系统会第一时间报警,经过确认后将流量切到没有问题的机房,从而确保整个系统的稳定。
系统使用 Fusion 进行持久化的数据存储,这部分数据相比 Codis 而言存储时间更长、容量更大,数据除了用于进行离线分析之外,我们用其作为 Codis 的兜底,保障系统数据层的健壮性。
除了上面提到的两个数据库之外我们还使用 ElasticSearch&Kibana 进行线上日志的存储 &检索;使用 HDFS 进行数据的长期归档保存,确保可进行长时间段的追溯;使用 DDMQ 进行业务数据的传递。
在整个计价系统演进过程中,系统从比较简单的计价器到如今复杂的价格系统,一路上面对非常多的挑战,下面从系统稳定性、计价准确性、迭代高效性三个方面进行介绍。
4.1 稳定性
计价系统作为业务主流程中的一环,稳定性是衡量计价系统的重要因素。在滴滴内部,我们用两个指标衡量稳定性,首先是不可用时长,第二是不同等级的事故数量。在稳定性方面我们做了大量的工作,本文从两个维度介绍:人、架构:
先说说人。系统的故障来源大致可分为两类,人为因素和自然因素。自然因素,常见的如网络波动、机器故障等,不常见的如断电、地震、火灾等,这些我们很难提前避免,只能做好预案建设;人为因素则是我们可以通过一些机制避免的,最常见的如逻辑 bug、系统设计问题等。为了降低人为因素导致的故障,我们从以下几个方面建立健全机制:
接下来说一下架构层面。这里介绍两点,非核心功能解耦及防御性编程。
非核心功能解耦指的是不在核心流程中的功能我们都尽量将其隔离出来,避免影响到主流程,如工具类、查询类等旁支功能,在计价系统中的判定标准就是在一次实际打车过程中如果没有这个功能是否可以继续进行,为此我们解耦出了多个模块,如配置平台、dealer 渲染模块、cratos 开放化计价模块等等。解耦带来的好处多种多样,首先就是故障异常的解耦,解耦出来的模块其稳定性、性能甚至是逻辑问题都不会干扰核心流程,其次是当真正的故障来临时,这些非核心功能都可以做到一键降级,比如 dealer 渲染模块,经过降级之后就没有费用明细页,但总价依旧保留,通过这种有损的降级,我们保障了打车的核心体验依旧是完备的。
防御性编程是一种系统设计思想,它是为了保证对程序的不可预见的使用不会造成程序功能上的损坏。具体在日常系统设计上有两部分,首先对所有外部依赖保持高度不信任,所有第三方依赖都需要有降级兜底方案,尤其是涉及核心功能的依赖,如数据库。在计价中,我们对大量的核心依赖都有降级兜底方案,如最重要的核心存储 Codis 我们有三层降级兜底,从内存、fusion 再到上游透传数据,确保打车过程中即使 Codis 全挂,虽然可能有损但不影响核心流程的继续。其次是在日常的编码过程中,需要确保每个函数的健壮性,对于入参,不能做预设应及时返回错误。『凡是可能出错的地方就一定会出错』,墨菲定律告诉我们不应该心存侥幸,对于日常的编码工作,要将稳定性时常放在心上。
4.2 准确性
在价格计算的准确性上以时间和里程的精准计算为例。
在计算时间时,所有时间都经过服务端的校准,避免人为因素导致时间误差。除此之外在行程中的时间计算是通过每秒一个坐标点的上报,可以将时间的计算精度控制在秒级,而我们的计费规则只会精确到分钟级别;对于上报上来的坐标点,我们也并非全盘接受,首先相邻坐标点经过严格校验,必须符合准入规则才予以采纳,对于异常的点,系统会进行记录和报警以及时发现异常。
在里程计算方面,首先两坐标点之间的距离计算并不是用直线距离计算而是使用球面距离,如下图公式所示:
其次手机 GPS 定位可能出现漂移,系统会将每个上报过来的点进行绑路处理,确保坐标点落在车道而非路的两侧,和时间一样,对于前后差异过大的两个坐标点,系统同样会判定无效,避免因为手机、系统或者人为因素导致距离计算的不精确。
4.3 高效性
作为与价格最密切相关的系统,业务方提出的需求是又多又快又复杂,计价团队为了快速响应业务方的迭代需求,提升中台复用价值,通过配置化、自助化支持了大量业务需求,下面从开放化计价和价格权益两方面介绍。
目前开放化定价与价格权益已经形成完整的精细化定价体系,成为价格这一重要领域的支柱体系。
当然,我们的产品和系统还有很多不完善的地方,欢迎大家提出宝贵的意见,帮助我们更好的成长,谢谢。
头图:Unsplash
作者:滴滴智能中台
原文:https://mp.weixin.qq.com/s/hV0_pDRBisr_vOwKpqjdYQ
原文:计价系统在滴滴的应用与实践
来源:滴滴技术 - 微信公众号 [ID:didi_tech]
转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
领取专属 10元无门槛券
私享最新 技术干货