eureka三级缓存源码级解析

服务端增量获取注册表

eureka 的三级缓存可以说是设计的整个中间件非常大的亮点,这里以增量获取注册表信息为例,直接从服务端开始进行分析

我们直接来到获取缓存的部分

@VisibleForTesting
    Value getValue(final Key key, boolean useReadOnlyCache) {
        Value payload = null;
			......
            if (useReadOnlyCache) {
                final Value currentPayload = readOnlyCacheMap.get(key);
                if (currentPayload != null) {
                    payload = currentPayload;
                } else {
                    payload = readWriteCacheMap.get(key);
                    readOnlyCacheMap.put(key, payload);
                }
            } else {
                payload = readWriteCacheMap.get(key);
            }
	      ......
        return payload;
    }

这里可以看到首先是从 readOnlyCacheMap 里面获取缓存,如果这个Map 没有获取到缓存,就会从readWriteCacheMap获取缓存,并且会填充 readOnlyCacheMap

假设 readWriteCacheMap 没有获取到缓
在这里插入图片描述

readWriteCacheMap 是google的一个缓存,这个缓存提供了定时失效,监听器等等功能,具体原理笔者也没有研究,结果是如果 readWriteCacheMap 没有获取到缓存就会调用 这里的 load 方法,而加载增量数据的方法是generatePayload()

这里以获取增量信息为例
在这里插入图片描述
这里的payload 其实就是将需要返回的信息封装了一下而已,具体获取数据的逻辑是在getApplicationDeltasFromMultipleRegions(…)

// 省略了部分代码
public Applications getApplicationDeltasFromMultipleRegions(String[] remoteRegions) {
        if (null == remoteRegions) {
            remoteRegions = allKnownRemoteRegions; // null means all remote regions.
        }

        boolean includeRemoteRegion = remoteRegions.length != 0;

        if (includeRemoteRegion) {
            GET_ALL_WITH_REMOTE_REGIONS_CACHE_MISS_DELTA.increment();
        } else {
            GET_ALL_CACHE_MISS_DELTA.increment();
        }

        Applications apps = new Applications();
        apps.setVersion(responseCache.getVersionDeltaWithRegions().get());
        Map<String, Application> applicationInstancesMap = new HashMap<String, Application>();
        try {
            write.lock();
            Iterator<RecentlyChangedItem> iter = this.recentlyChangedQueue.iterator();
           
            while (iter.hasNext()) {
              .......
            }

            ......
            ......
            Applications allApps = getApplicationsFromMultipleRegions(remoteRegions);
            apps.setAppsHashCode(allApps.getReconcileHashCode());
            return apps;
        } finally {
            write.unlock();
        }
    }

这里我们来关心一个 recentlyChangedQueue 的属性
这个里面其实是统计了最近三分钟内进行的注册,修改和剔除的服务实例信息,拿增量信息拿的其实就是这一部分的信息,然后将增量信息同步缓存,同时返回给客户但,保持数据的一致性

缓存的数据更新

上面介绍了缓存数据的获取,下面来介绍缓存数据的更新
首先只读缓存不会主动去同步 读写缓存 ,读写缓存也不会主动去同步 注册表或者是最近三分钟的队列信息

再服务端中,有一个定时器,每30s将读写缓存的信息同步到只读缓存
下面直接来看这个定时器的逻辑
在这里插入图片描述这里需要注意的是,遍历的是读写缓存的key,如果读写缓存因为180s超时,或者是被迫失效(注册表变更),那么在进行
读写缓存同步到只读缓存 判断内容是否一样的时候就会为false,因为读写缓存被清空了,所以取出 来的内容为null,所以填充到只读缓存的内容就是null了,那么客户端获取这部分数据的时候,发现 是null,就会又从读写缓存里那,拿不到就加锁从register里拿(增量其实是从3分钟队列里拿),那 么这个时候,拿到的就是正确的数据,然后刷新到客户端缓存

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值