写点什么

信息聚合接口的实现与展望

用户头像
QiyihaoLabs
关注
发布于: 2020 年 11 月 27 日
信息聚合接口的实现与展望

需求背景

每个公司都有自己的一套账号体系。我们也不例外,有一套自己的账号体系,使用 uid 作为唯一的标识。同时,围绕 uid,也会产生很多属性。比如用户本身有头像和昵称。用户还可以通过认证等方式成为一个自媒体 UP 主(以下简称 UP 主)。UP 主还可以有蓝 V 认证、黄 V 认证、认证语等。除此之外,UP 主还可以发布视频,收到点赞、评论、关注等信息。这些信息分散在公司的各个服务系统中,各个显示入口按照自己的逻辑组装数据,并按照自己自定义的一套规则进行展示。这么做其实有一系列问题:

  • 开发资源的浪费。各个开发团队重复造轮子,同样的业务逻辑需要多次开发

  • 各个业务入口显示的规则和内容不一致,用户体验不统一。比如 A 端优先展示蓝 V 标识、B 端则所有标识按照优先级,所有 V 标全部展示

  • 对接成本较高,每个团队都需要自己去对接一系列三方团队,对接成本较高

为了解决以上的问题,我们决定造一个牛 A 和牛 C 之间的轮子。通过提供一个通用的信息聚合接口,统一对外提供服务。业务入口只需要输入 uid,就可以查询该用户相关的信息。不需要关心业务优先级和具体的数据来源。只需要按照需要进行数据读取即可


高并发接口背后的十八般武艺

基于以上的业务背景介绍,可以看出我们需要一个统一的信息聚合接口,该接口的主要特点是入口较多,高并发,延迟尽可能的低。可以看出,这是一个典型的 toC 的高并发业务场景。工欲善其事,必先利其器。我们先来看看面对这类场景,我们的工具箱里都有哪些工具。

  1. 缓存。做过 toC 需求的小伙伴对缓存应该并不陌生。基本上 C 端接口到哪,缓存就跟到哪。可以说缓存是高并发的不二法门。

  2. 异步化。和缓存一样,异步化也是我们工具箱中的高并发利器。如果请求依赖多个数据源,而这些数据源直接是相关独立的,我们可以并发的去请求这多个数据源。最后在所有数据源都返回之后,通过数据拼装,把数据按照规定的格式返回给调用方

  3. 内部调用 rpc 改造。rpc 调用比 http 消耗更少的资源,因此为了减少资源开销,内部调用也可以进行 rpc 改造。使用更少的资源,提供更为高效的服务,

  4. 热点数据同步。几乎所有的业务场景涉及的数据都可以分为热点数据和非热点数据。热点数据顾名思义是访问频率高的数据。如 12306 的热门车次,淘宝、拼多多大促期间首页推荐的商品等等。这些热门数据的访问频率很高,为了提供更好的服务,我们可以优先把这些数据缓存到高速缓存中,比如 redis

  5. 减少不必要的第三方请求。我们提供的服务接口背后一般都会依赖不同的第三方服务。但是由于业务调用方的不同,并不是所有的业务方每次请求都需要拿到全部的字段。可能只需要其中的一部分字段。因此我们可以基于业务特点把返回的字段进行归类。调用方可以根据自己的需要按需请求字段。从而避免无效的第三方请求,节省机器资源

  6. 提前过滤无效请求/通过消息队列削峰填谷。根据业务特点,还可以对请求提前做一些过滤。或者对实时性要求不高的场景,我们可以采用消息队列的方式,对请求进行削峰填谷。



聚合接口在业务中的实践

本节主要会介绍,高并发是如何在我们平台落地的

  1. 缓存。上一节也介绍了,缓存技术作为高并发的利器,在互联网开发中可以说是无处不在。经过技术选型,最终我们选择了阿里的 jetcache 框架,通过二级缓存的方式承接业务流量。之所以选择二级缓存(本地缓存+redis 缓存),就是避免本地缓存失效后,大量请求直接打到第三方服务,造成服务雪崩。有了 redis 缓存,本地缓存失效后,绝大多数请求都会落到 redis 上。而针对第三方请求的服务,只有 redis 失效,才会请求一次第三方服务。有效的减轻了第三方服务的压力。

  2. 异步化。针对互相独立的数据源,异步化也可以有效的加快请求速度。比如我们常见的点赞数、关注数场景,这两个数量之间没有直接的关系。我们又分别需要去不同的地方获取,因此,我们可以使用异步线程去分别获取点赞、评论数,等待两者都返回后,再返回给业务方。我们使用的 java8 自带的 CompletableFuture 框架对异步请求进行管理

  3. 热点数据同步。针对热点数据,提前同步到高速存储中,优先保证这部分热点数据的返回。根据 20-80 原则,热点数据(即经常被访问的数据)实际上只占全量数据的比较少的部分。但是却占整个请求的很大一部分。可以通过提前把这部分数据缓存的方式,来提升用户的使用体验。实际上,我们也是这么做的。我们提到的 UP 主用户,占全量用户的很少一部分,但是业务方绝大多数的请求都会落到这些用户上。因此我们开发了独立的同步程序,监听这类认证用户的变更,同步信息到 redis,保证这类请求的数据实时性和稳定性。其他用户通过缓存来提供服务,保证服务稳定性的同时,牺牲一部分实时性。


未来与展望

该信息聚合接口目前已经部署到线上环境,并持续的提供稳定高效的服务。当然,技术的优化没有止境。本节主要探讨该接口未来的一些可能性。

  1. 使用 graphql 改造。GraphQL 是一种描述请求数据方法的语法,通常用于客户端从服务端加载数据。本文不对其做过多介绍,感兴趣的同学可以自行 google。graphql 的主要特点之一是客户端可以指定具体所需的数据。这个特点和爱奇艺号信息聚合接口的特点是一致的。业务方可以根据自己的需求去定制请求,业务方只需要指定自己感兴趣的字段,拼接好请求发送给调用方。调用方对请求进行解析后,也只有限请求这些字段背后所需的三方服务。而且 graphql 是支持异步化的。多个字段之间只要没有依赖,可以并行获取,自动拼装。而所有的这些都不需要增加额外的代码


  1. k8s&knative。云原生是目前微服务发展的一个趋势。其中 k8s 作为云原生的基础设施,这两年也广为流行。因此,未来,我们的服务可以迁移到 k8s。利用 k8s 提供的基础能力提供更为高效的服务。也可以使用 knative 提供的一些基础设施,对服务进行进一步的优化。比如基于服务访问 qps 等,服务自动扩缩容,实现服务按需调用。


发布于: 2020 年 11 月 27 日阅读数: 66
用户头像

QiyihaoLabs

关注

还未添加个人签名 2020.01.21 加入

还未添加个人简介

评论

发布
暂无评论
信息聚合接口的实现与展望