乐趣区

架构设计我的一个支持异步拉取数据和本地缓存client是如何设计的

最近的工作内容是封装一个高性能的 sdk,以便和我们的配置中心进行交互,这里整理一下我是如何设计

1. 需求分析

  • 我们要支持和配置中心的交互(网络 IO)
  • 支持客户端缓存功能,并且支持断电重启(内存缓存 + 文件缓存)
  • 配置中心没有推送功能,sdk 需要进行轮询(使用 NIO 网络模型进行轮询)

    • 这个点其实设计的并不好,最好是开启一个长链接,由服务端推送请求是最佳实现,但是因为配置中心和客户端之间有一个中间层,无法实现长链接,不过这两个在实现上是类似的

2. 任务分解

  1. 针对网络 IO 提供两套模型
  • 当缓存中没有所需要的数据的时候,使用 BIO 直接读服务端(缓存击穿)
  • 当缓存的存在的时候,将缓存的数据添加到轮询队列中,等待下一次异步同步更新
  1. 针对缓存设计
  • 内存缓存:除了需要提供一个数据缓存,还需要提供一个状态同步集合来标记缓存中数据的状态,比如是否超时,是否有效等

针对这个情况我们需要实现一个功能类 — 状态处理类,通过这个类来处理缓存中状态同步集合的状态,并同步处理数据缓存对应的状态

ps : 为什么设计成数据和状态分离 -> 为了更高的可控性和解藕 1. 如果需要状态特殊处理的时候只需要拿出状态队列就可以进行处理了不需要动缓存 2. 如果状态需要添加字段或者逻辑,只需要修改对应的状态队列即可,不需要修改数据缓存

  • 文件缓存:这个本质上很内存缓存相似,只有一个点就是当使用 nio 进行数据同步的时候,nio 从网络中拉取的新数据需要同步更新缓存和文件,此时的文件操作应该使用 nio 保证不堵塞。
  1. 轮询方法

我在框架中使用的 NIO 网络框架是 vert.x 其实可以理解成 java 中的 promise 方法

这里我做的轮询逻辑其实非常简单过程如下

  1. 拿到需要进行轮询队列
  2. for 循环发起 NIO 网络请求,并且处理结果
  3. 更新缓存状态(更新缓存,处理超时等问题)

还需要那些改进?

  • 需要添加一个速率控制器,考虑这样一个场景如果轮询发起的请求过大,将可能会把配置中心打垮,所以 sdk 需要控制请求的速率动态的调整 qps 来保证服务的稳定。

3. sdk 整体的架构图如下

退出移动版