Spring Cloud 2.2.2 源碼之十二Eureka服務處理獲取服務請求一

大致流程圖

在這裏插入圖片描述

獲取全量服務信息

我們來講下客戶端獲取全量服務信息的時候服務端是怎麼做的。調用的是ApplicationsResourcegetContainers。主要就是創建一個緩存的Key對象,對象的屬性值ResponseCacheImpl.ALL_APPS表示的就是全量,也就是獲取緩存用的,緩存其實是個map。然後調用responseCache.getGZIP獲取全量的服務信息。

 @GET
    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) {


       	...      
		//創建一個緩存對象
        Key cacheKey = new Key(Key.EntityType.Application,
                ResponseCacheImpl.ALL_APPS,//全量
                keyType, CurrentRequestVersion.get(), EurekaAccept.fromString(eurekaAccept), regions
        );

        Response response;
        if (acceptEncoding != null && acceptEncoding.contains(HEADER_GZIP_VALUE)) {
            response = Response.ok(responseCache.getGZIP(cacheKey))//獲取壓縮的數據
                    .header(HEADER_CONTENT_ENCODING, HEADER_GZIP_VALUE)
                    .header(HEADER_CONTENT_TYPE, returnMediaType)
                    .build();
        } else {
            response = Response.ok(responseCache.get(cacheKey))
                    .build();
        }
        ...
        return response;
    }

Key緩存的對象

這個對象沒什麼好看的,就是他重寫了hashCode方法,也就是讓map可以比對怎麼樣是同一個對象,map是根據hashCode相關算法比對的:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
可見不同的對象,只要傳入的屬性值相同,那麼hashKey相同,hashCode()返回值就相同,在map中認爲是同一個Key,就可以獲取同一個對象。

ResponseCacheImpl的getGZIP

Key對象傳進去,獲取值,默認是用只讀緩存的,其實內部有三級緩存,只讀,讀寫,註冊表。
在這裏插入圖片描述

getValue獲取值

可以看到,默認先啓用讀緩存readOnlyCacheMap,如果找到就返回了,否則再看讀寫緩存readWriteCacheMap,如果寫緩存不存在,就會從註冊表中獲取,這個後面會說這麼做的,存在的話就直接返回,然後都要保存到讀緩存中。這裏爲什麼要這樣設計,讀寫分離,就是爲了提高性能,寫的時候不會影響到讀,讀也不會影響到寫,當然這裏會用定時器來進行數據的同步,但是不是實時的,爲了性能,保證數據最終一致。
在這裏插入圖片描述
這兩個緩存的類型,LoadingCache是谷歌緩存框架裏的,提供了一個方法,就是不存在的時候要怎麼辦,這裏不存在的時候就可以去註冊表中獲取:
在這裏插入圖片描述

readWriteCacheMap不存在的處理方式

如果讀寫緩存不存在,就會去註冊表中獲取,哪裏看出來的呢,創建的時候:
在這裏插入圖片描述

generatePayload

看下面的。
在這裏插入圖片描述
然後直接用JSON編碼後返回。
在這裏插入圖片描述

registry.getApplications()做了什麼

在這裏插入圖片描述
內部就是獲取了註冊表的所有信息,封裝成Applications對象:
在這裏插入圖片描述
最後計算出AppsHashCode後返回:
在這裏插入圖片描述

registry和Applications的結構大致如圖

其實就是做了類型的轉換,好編碼後發到客戶端,數據還是這些數據。
在這裏插入圖片描述

三級緩存基本講完了,首先是讀緩存,然後讀寫緩存,最後註冊表,爲了讀寫分離,後面講他們怎麼進行數據同步的。

好了,今天就到這裏了,希望對學習理解有幫助,大神看見勿噴,僅爲自己的學習理解,能力有限,請多包涵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章