当客户端申请全量更新的时候,会调用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);}@VisibleForTestingString 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();    }}@VisibleForTestingValue 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(),间接从注册表数据拿值。

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