基础概念
「富客户端」是和「瘦客户端」相对的一个概念,我们平时编程过程中涉及到的多是瘦客户端,富客户端会将更多的逻辑做在客户端上,它们俩各有优缺点。
富客户端
优点:
- 有一部分逻辑可以在 C 端客户端完成,避免了网络开销
- 客户端体验良好,可以完成更复杂的功能
缺点:
- 客户端逻辑可能会占用用户资源,对用户硬件资源要求较高
- 如果服务端的更新逻辑影响到了客户端,客户端也要同步更新,成本高
瘦客户端
优点:
- 客户端不被服务端的逻辑影响,通常仅需要感知接口协议,逻辑较薄
- 不占用客户端额外的资源
缺点:
- 高并发场景下,一些不必要的网络开销会被放大
原理阐述
那么为什么要引入「富客户端」这个概念呢?
其实在阿里等电商平台中,就经常会用到下游提供的富客户端接口,比方说省钱卡套餐在查询红包资产核销状态的时候,就需要调用下游红包资产的富客户端接口进行查询,由于红包资产查询的 QPS 可能很高,因此下游专门优化并提供了这个富客户端接口。我们来通过架构图进一步理解富客户端的优化效果,整体架构是「分布式系统」:
瘦客户端
先看下面瘦客户端的场景,RPC Server 暴露给上游服务 Controller 的是瘦客户端,在我们平时编码的时候,其实就是简单的接口协议格式,比方说 Thrift.client 接口调用格式,然后所有的下游逻辑都包在 RPC Server 中,也就是由 Provider 去实现。这样子上游其实也不用关心下游的实现逻辑,实现了 RPC 调用的解耦,下游逻辑的收口。
但是再仔细分析下,如果命中缓存的场景下,b.client ——> b.server -> Redis 获取,网络开销有两次,在低流量场景下倒还过得去,但是在高流量低时延的场景下,这条链路就值得优化了。其实判断是否命中缓存这个逻辑是相对较薄的,优化方向就是将其做到 b.client 逻辑中,以类似 Maven 包的形式提供出去。
富客户端
在 b.client 中多做了一个逻辑,Controller 在调用 RPC 时,先去缓存取数据,命中了就直接返回,也就是在缓存命中的场景下,减少了一次网络开销。增加的逻辑判断,其实是下游逻辑封装提供的,将缓存判断逻辑+RPC调用逻辑封装到 b.client 中,暴露给调用者,这也就是「富客户端」的概念。
这一次网络开销的节约在高并发场景下是非常有必要的,比如省钱卡的我淘入口强卡 50ms 的接口 RT,接口中依赖了下游红包资产查询接口,下游服务就必须提供这种富客户端接口,帮助我们进行 RT 优化。