业务背景
闲鱼作为一款C2X的app,与淘宝、天猫等B2C的业务模式存在天然不同。个人卖家也是普通的消费者,很多个人卖家相比专业卖家,并不淘宝清楚如何卖出自己的商品,问题主要表现在以下两个方面:
商品信息不足。闲鱼采用轻发布模式,用户只需要上传几张照片,简单描述一下商品信息,即可在一分钟之内完成发布流程。轻发布模式迎合了用户快速发布的体验,但也导致了商品信息不足的问题。
商品定价不合理。有些卖家用户误判了自己商品的市场行情,导致定价和买家预期存在偏差,降低了买家的购买意愿。
所以问题来了,如何在既保证轻发布的同时,提升商品的有效信息量,增加商品宝贝的吸引力,促进成交呢?
解决思路
在上述问题背景下,我们想到了做任务的方式引导用户。具体做法是:在轻发布的前提下,通过做任务的方式引导卖家补全商品信息或引导商品降价,从而促进成交。一方面,商品关键属性的信息补全了,价格变得合理了,就有更多的买家愿意浏览商品并成交。另一方面,也帮助我们技术小二更好的理解商品的特征,从而更精准地推荐给需要的买家。
淘宝技术实现与系统沉淀
在这个解决思路下,我们创造了Tellus-基于用户&商品的任务系统。有些同学可能问了:“公司内部难道没有类似的系统吗?任务系统应该比较常见吧?”经过调研,发现已有的内部系统大部分是基于用户的任务系统,而闲鱼的任务系统是基于用户&商品维度的,这样的特点导致我们无法复用现有的任务系统,只能通过自研。
整体系统结构图
任务的生命周期分为创建任务、展示任务和完成任务。
任务创建模块
创建任务的难点在于之前提到的数据来源复杂的问题,因为任务创建的来源较多,为了降低接入成本,Tellus的任务创建模块使用消息队列来做事件解耦。Tellus使用MetaQ作为消息队列。MetaQ是一款阿里自研分布式、队列模型的消息中间件(RocketMQ)。基于发布订阅模式,有Push和Pull两种消费方式,支持严格的消息顺序,亿级别的堆积能力,支持消息回溯和多个维度的消息查询。通过消息定制,所有的数据源统一发送创建任务的消息,Tellus系统监听此类消息并且根据业务逻辑创建对应的任务,很好地解决了复杂消息源的问题。
任务展示模块
当任务创建后,如何展示任务呢?展示流程如下:
闲鱼币我们通过AB实验进行了全方位的探索,Tellus系统支持了丰富的任务类型, 我们尝试了单个任务和组合任务。
单个任务展示
组合任务展示
卖家还支持基于用户维度(例如连续擦亮任务)的和基于商品维度(例如选商品成色)的任务。Tellus系统同时也实现了任务频次的定制,任务可以一次性完成,也可以重复做,可以按照特定顺序完成组合任务,也可以乱序完成,给业务提供了灵活的可配置型。
任务完成模块
任务的完成模块分为主动完成逻辑和被动完成逻辑,主动完成可分为任务成功和任务失败,被动完成属于用户的某些app行为触发了完成任务的逻辑,从而在不知情的情况下完成了任务,比如在重新编辑商品的时候添加了商品成色,那么添加成色的任务就自动完成了。不同任务还可以实现个性化的激励步骤,Tellus通过策略模式的设计,将接口开放给业务方开发,每个任务的完成,用户都可以获取到一定的激励,这些激励根据业务的不同而不同,通过接口开放,业务方开发只需要遵守接口的协议,便可以实现定制化开发,完成不同的任务激励机制。
技术选型
在整个任务的生命周期过程中,还有一个始终都绕不开的难题,就是数据该如何存储,任务数据主要分为两类:一类为任务的详细数据;另一类为任务的元数据。针对任务的详细数据,首先要考虑的是关系型数据库还是非关系型数据库,关系型数据库支持事务,可以进行复杂的联表查询,这些对于任务系统并非必须和必要的,任务系统对数据的关联性要求不高(任务数据之间几乎是相互独立的),但是对于数据的存com储量级要求较高(百亿级别)。支持海量数据存储的Table store进入了我们的视野。表格存储(Table Store)是阿里云自研的NoSQL多模型数据库,提供海量结构化数据存储以及快速的查询和分析服务。表格存储的分布式存储和强大的索引引擎能够支持PB级存储、千万TPS以及毫秒级延迟的服务能力。除此之外,Table Store还兼具以下优点:
Table Store还是一种全托管的数据库。使用表格存储只需专注于业务研发,无需担心软硬件预置、配置、故障、集群扩展、安全等问题,在保证高服务可用性的同时,极大地减少了管理及运维成本,这样可以使我们把精力全部放在业务的开发上。
查询能力强。除了支持主键查询,表格存储还支持多元索引、全局二级索引。
高可用。表格存储将数据的多个备份存储在不同机架的不同机器上,并会在备份失效时进行快速恢复,提供99.99999999%(10个9)的可靠性。
数据强一致。表格存储保证数据写入强一致,并保证数据 3 副本均写入磁盘,且所有数据保持一致。写操作一旦返回成功,应用程序就能立即读到最新的数据。
基于上述优点,Table Store比较好的满足了我们数据存储的需求。针对任务的元数据,考虑到使用频率,我们也创建了缓存进行读写,对于任务系统的元数据,我们选取了guava cache作为缓存。原因是guava cache请求快速且简单易用。任务元数据数据量较小,即使每个节点都存储一份缓存,开销也不大,这种情形使用分布式缓存比较重,意义不大。
业务效果
Tellus由于其功能支持的多样性,可拓展性,以及可配置性的多种特点,在短时间内可以支持大量不同业务场景的上线,这里我们以超级曝光和存量诊断也为为例,具体说明一下。超级曝光针对新发商品在商品发布时弹出一个弹窗,引导用户进入组合任务页面完成任务,完成后用户可获得超级曝光特权。存量诊断针对存量商品,在宝贝下方透出第一个任务信息,引导用户进入组合任务页面,完成组合任务。上线后,任务完成率翻倍。
开发效率提升
对于Tellus来说,比较大的一个挑战是新增任务数量较多,较短时间内需要支持数百个任务,这几乎是不可完成的工作。为了支持业务的快速试错,并且降低开发成本,Tellus主要做了两个方面的优化,一个是任务模版化,另一个是支持任务的可配置化。先说说任务的模版化:我们发现任务从表现形式上可以抽象为单选类、多选类、确认类、跳转类等等。将每类任务定制为一个模版,视觉同学针对模板进行视觉抽象,固定展示样式,服务端根据展示样式抽象模板类型,前端完全基于服务端数据驱动,前后端的协议格式举例如下:
新增任务时,只需要套模版即可,减少了很多重复开发的工作量。再说下任务的可配置化:在任务模版化的基础上,我们发现对于某些任务,任务的逻辑基本一致,只是对应的任务文案不同。Tellus针对这些简单任务,支持了任务可配置化的开发,目前1.0已经开发完成,原本需要改代码才可以新增一个任务,如今只需要改配置文案即可。后续2.0版本将做运营页面的开发,运营同学只需要在页面上配置即可,不再需要开发人员介入,从而大幅提高开发运营效率。
后续计划
Tellus后续计划与Omega和Hermes平台对接。Omega是闲鱼一个实时事件采集系统,通过日志采集用户行为事件,通过规则计算,对符合条件的用户调用Hermes精准触达。Hermes是闲鱼的触达系统,之前的公众号文章也有介绍。举个例子:用户发布商品,可以通过omega实时采集这一事件,然后实时生成该商品对应的某些任务,这样相较于消息的方式设计更合理,后期可拓展性更高;和Hermes的联动,更多地体现在通过push等方式去促使用户完成任务,增加任务的曝光。
Tellus还计划增加一系列激励措施,鼓励用户做任务,最近我们在和闲鱼币的同学进行对接,对于完成某类任务的用户,通过给与一定量的闲鱼币,从而激励用户更多地完成任务。