关于eureka:Eureka-服务发现Server

40次阅读

共计 2383 个字符,预计需要花费 6 分钟才能阅读完成。

当客户端申请全量更新的时候,会调用 ApplicationsResource#getContainers 这个办法。如果是增量,会调用 ApplicationsResource#getContainerDifferential 这个办法。他次要是获取只读缓存的内容,如果只读缓存不存在,返回只读读写缓存的内容。

public Response getContainers(@PathParam("version") String version,
                              @HeaderParam(HEADER_ACCEPT) String acceptHeader,
                              @HeaderParam(HEADER_ACCEPT_ENCODING) String acceptEncoding,
                              @HeaderParam(EurekaAccept.HTTP_X_EUREKA_ACCEPT) String eurekaAccept,
                              @Context UriInfo uriInfo,
                              @Nullable @QueryParam("regions") String regionsStr) {

    // 其余略
    response = Response.ok(responseCache.get(cacheKey))
                .build();
    // 其余略
    CurrentRequestVersion.remove();
    return response;
}

public String get(final Key key) {return get(key, shouldUseReadOnlyResponseCache);
}

@VisibleForTesting
String get(final Key key, boolean useReadOnlyCache) {Value payload = getValue(key, useReadOnlyCache);
    if (payload == null || payload.getPayload().equals(EMPTY_PAYLOAD)) {return null;} else {return payload.getPayload();
    }
}

@VisibleForTesting
Value getValue(final Key key, boolean useReadOnlyCache) {
    Value payload = null;
    try {
        // 应用只读缓存
        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);
        }
    } catch (Throwable t) {logger.error("Cannot get value for key : {}", key, t);
    }
    return payload;
}

下面的代码流程如下:

readOnlyCacheMap 的值是怎么来的呢?
Eureka – Server 服务启动 PeerAwareInstanceRegistry#init 办法中提到了 ResponseCacheImpl 构造函数中,没 30 秒会把 readWriteCacheMap 的值赋值给 readOnlyCacheMap。

ResponseCacheImpl 初始化的时候,咱们看到他默认 180 秒后会过期。

this.readWriteCacheMap =
    CacheBuilder.newBuilder().initialCapacity(serverConfig.getInitialCapacityOfResponseCache())
            .expireAfterWrite(serverConfig.getResponseCacheAutoExpirationInSeconds(), TimeUnit.SECONDS)
            // 其余略;

Eureka – Server 服务启动中提到,PeerAwareInstanceRegistryImpl#syncUp() 每次注册都会被动清空 readWriteCacheMap 的值。

ResponseCacheImpl 初始化的时候,还有一个 build 办法

this.readWriteCacheMap =
        CacheBuilder.newBuilder().initialCapacity(serverConfig.getInitialCapacityOfResponseCache())
                // 其余略
                .build(new CacheLoader<Key, Value>() {
                    @Override
                    public Value load(Key key) throws Exception {if (key.hasRegions()) {Key cloneWithNoRegions = key.cloneWithoutRegions();
                            regionSpecificKeys.put(cloneWithNoRegions, key);
                        }
                        Value value = generatePayload(key);
                        return value;
                    }
                });

当 readWriteCacheMap 没有值的时候,他会调用 load 办法。如果是全量,就会调用 registry.getApplications() 这个办法,如果是增量会调用 registry.getApplicationDeltas(),间接从注册表数据拿值。

所以在服务发现的时候,都是走缓存,提高效率,然而为了保证数据的一致性,还会定期更新、清空缓存。

正文完
 0