闲鱼在数据聚合上的探索与实践
副标题[/!--empirenews.page--]
概述 随着业务的不断扩张,各种运营活动越来越多,原有的前端渲染-后端提供业务接口的开发方式对于一个生命周期可能只有几天的活动来说成本巨大。闲鱼在降低开发成本,提高整体效率上做了一些尝试和实践。本文介绍闲鱼从数据聚合方面进行了一些探索和尝试,以及Graphql的引入给闲鱼带了研发效率的提升。 背景 长期以来,前端和后端开发中面临一个矛盾:前端希望页面只获取结构化数据,能够直接渲染出页面组件;后端则希望只提供业务领域API服务能力,数据组装和处理由前端完成。mock数据,联调等低价值的工作会耗费很多的成本,原有的开发模式已跟不上业务快速发展的节奏。 因此我们希望前端可以直接获取数据,后端又能从重复的、低价值的消费型开发中解放出来。 ![]() 数据聚合是我们解决的一个思路。 1. 数据聚合的解决方案 数据聚合是将多个服务请求一起打包给服务端,服务端一次性返回相应请求的结果,这种方式可以降低网络耗时,在数据处理上也会更方便。在入参语法上也有扩展的可能性,比如依赖调用等,是一种比RESTFul更加灵活和高效的查询方式。 ![]() 在数据聚合的调用下,由于服务端的业务领域接口已经存在,这些接口认为是可靠的,联调成本将会大大降低,在一些测试环境发生异常的情形,前端甚至可以直接在线上测试。 设计原则
2. 数据聚合1.0 闲鱼服务端开发了第一个数据聚合服务。 通过将底层服务暴露出来,从请求总入口进行并发调用具体的服务接口,页面多个服务查询可以一次性将所有的数据返回给前端。 调用过程如下: ![]() 这个框架有如下几个特点:
全并发调用,调用的多个服务API均采用并发方式调用,耗时低 此外我们对其语法结构和功能上进行了扩展:支持字段选取,依赖调用,循环依赖检查,别名等功能: ![]() 2.1 上线效果 上线半年内,数据聚合服务支撑了30+的页面上线,占同类需求的80%以上,降低了两端的开发成本超过50%。 2.2 闲鱼聚合服务上线后存在以下问题: 数据响应结构对调用方不够友好,虽然支持依赖调用,但是返回的数据是平级展现形式,对于一些批量接口来说,返回的结构往往是Map结构,这需要调用方进一步处理,增加了复杂度; 安全性问题。multiquery的查询串没有经过加密,一些非法的请求可能会修改查询语句带来系统风险;而且对于一些敏感数据需要加密或脱敏处理,multiquery语法结构上缺乏数据处理的扩展点 研发体系不完善:缺乏对服务的meta信息透出,导致调用方不清楚要用哪个服务,入参是什么出参是什么,双方存在一定的沟通成本。没有ide支撑,书写起来比较困难。 3. GraphQL-像写sql一样拼装数据 3.1 什么是Graphql Graphql (https://graphql.org ) 是 facebook 推出的一种数据查询语言,其设计的目的是要将不稳定的数据组装部分从稳定的业务数据逻辑中剥离,使数据控制逻辑前移,开发模式由“下发数据”转变成“取数据”的过程。 ![]() Graphql的优势: 结构化清晰:所见即所得,输入和输出结构一致,前端需要什么数据字段,就在ql上填写什么字段,同时支持多层级结构,也可以平级展现,由调用方根据业务决定合适的输出形式。 精细化场景控制:即便是类似的场景,需要的数据也可能不完全相同,graphql中没有一个数据是多余的 数据处理可扩展性强:graphql提供了很多Directives满足日常的开发需求,甚至支持js代码, 开发者也可以自定义一套工具库来扩展 3.2 GraphQL接入应用改造 闲鱼选择了TQL作为Graphql的服务端实现。Tql是淘宝提供的对GraphQL的java实现,并解决了开源版graphql的很多局限性和痛点,提供了很多特性,使graphql能够低成本部署在应用上。 接入简单,代码侵入性低:去中心化的设计,不依赖二方服务,应用系统直接引入可用 研发体系支撑:提供了ql编写的在线ide,可展示各个服务的meta信息,提高了开发效率,书写提示,执行耗时日志,调用场景监控等功能便于服务性能优化 多执行策略:提供了并发执行策略和异步执行策略,在多服务调用和层级调用场景上保证了ql的高效运行; 合并调用:执行前合并所依赖的上游数据集中的元素,这样我们就可以充分利用批量接口查询,而不是单个多次调用,性能显著提高 安全性提升: graphql语句从前端请求到服务端,用签名的方式来避免查询串被篡改 3.2.1服务端改造
Function入参改造: 后台的服务参数对于前端视角可能不同(参数过多,影响数据的参数等) 非批量Function出参:一般无需改造,同上 支持批量的Function改造,返回结构必须是有序List 非标准DO参数:由于输出是JSON,存在循环依赖的java对象使用fastjson输出时会造成栈溢出 开发GraphQL API 下面的示例可以提供一个Graphql的API。@GraphQLDataFetcher 注解表示该方法可以作为Graphql的数据源,supportBatch = true表示支持合并调用,执行前会将依赖的数据结果合并成一个List作为入参; (编辑:云计算网_泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |