抽丝剥茧 分布式服务框架设计 缓存优化篇

1、内容概述

        前面的2篇文章从理论设计到编码落地 我们研发了一款轻量级的分布式服务框架 cheese。如果你看过的话相信你肯定知道 cheese 的工作流程。虽然实现了服务注册、服务发现以及远程调用的三个基本功能,但是还是存在一些问题,我们今天就来分析一下有什么问题、怎么解决。

 关于Cheese这个框架 不知道的小伙伴可以查阅一下前面的文章

抽丝剥茧 分布式服务框架设计 理论设计篇

抽丝剥茧 分布式服务框架设计 实战落地篇

2、问题引入

                我们回到之前给出的cheese的架构图上

具体的工作流程是 tom 启动的时候 将自己的服务 通过 RegistServer 组件注册到 Zookeeper 上,当Jerry 需要远程调用 Tom 对外提供的接口的时候 就通过 DiscoveryServer 组件 从Zookeeper获取到Tom的服务地址,再交由 RemoteServer 组件完成远程调用。过程如下

我们不难发现上述过程存在一个问题,Jerry 每次去调用Tom的接口 都要先访问一次Zookeeper,这样是很不合理的,至少存在两个问题

1、多一次访问 Zookeeper,增加了额外的开销

2、假设 Zookeeper 连接出现服务中断,Jerry无法调用到Tom 

3、解决方案

        对于这两个问题 其实也好解决,但是要想解决的完美还是有一些难度的。这里最容易想到的解决方案就是在Jerry 第一次访问 Tom 的时候 就把Tom 的服务信息 在本地维护一份,这样后续再请求Tom的时候就直接从本地获取,不再访问Zookeeper获取了,这样后面即便是 Zookeeper 服务出现问题了,Jerry 也能找到 Tom 。

 整个交互的过程 如上图所示。引入了 LocalCache 组件 看着像是解决了我们前面提到的问题。那么我们怎么设计  LocalCache 呢。

4、缓存设计

4.1、LocalCache 设计

        从前面的分析上来看 LocalCache 需要维护Tom的服务地址,更确切的说应该是需要将 Zookeeper上的服务列表保存一份在本地(自己需要的服务)。举个例子,假设Jerry 需要远程调用Tom的接口 有三个,那么就需要将这个三个接口的服务都维护在自己的LocalCache组件中。

我们很容易的想到 LocalCache 组件内部需要维护一个数据结构,并且至少需要有3个方法,分别是初始化init 方法 以及获取和保存的方法。我们可以先设计一个接口

public interface CacheServer<T> {

    /**
    * @Description  缓存初始化
    * @Date 2024/11/4 下午 22:48
    * @Author wcan
    * @Version 1.0
    */
    public void init();

    /**
    * @Description 通过key 获取值
    * @Param [key]
    * @return java.lang.Object
    * @Date 2024/11/4 下午 22:49
    * @Author wcan
    * @Version 1.0
    */
    public Object getData(String key);

    /**
    * @Description 通过Key value的形式保存数据
    * @Param [obj]
    * @return void
    * @Date 2024/11/4 下午 22:49
    * @Author wcan
    * @Version 1.0
    */
    public void saveData(String key,T obj);

}

 这里为了兼容复杂的数据结构,引入了一个泛型。

4.2、LocalCache 添加在哪里

        我们已经勾勒出了 LocalCache 整个架子了,那么在 cheese 中 这个组件该怎么使用呢,应该将这个组件组装在哪里呢?我们思考一下,Jerry 远程调用 Tom 的时候 会先通过 DiscoveryServer组件 获取 Tom 的服务信息,获取成功后 由 RemoteServer 组件去远程调用  

 很显然,我们将  LocalCache 组件组装在1和3的地方是个不错的选择。

4.3、 WatchEvent 组件

        需要注意的是,假设Tom下线了,这个时候Zookeeper上是会清理Tom的服务信息的,这个时候我们本地的  LocalCache 也需要同步的修改。这就涉及到了Zookeeper和本地  LocalCache组件之间的数据同步了。所以我们还需要一个 WatchEvent 组件,该组件负责同步数据。

4.4、整体流程设计

1、当 Jerry 请求Tom的时候 先从LocalCache  组件中查询 Tom 的服务信息(IP或者协议)。

2、如果缓存命中了就直接使用缓存中的信息,通过RemoteServer 组件发送请求。

3、如果缓存未命中,则通过DiscoveryServer 查询Zookeeper。

4、将从Zookeeper获取的信息写入LocalCache中。

5、当Tom下线的时候 Zookeeper 会删除Tom相关的信息,这个时候Zookeeper会通知到 cheese。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值