12 張圖 | 深入理解 Eureka三層緩存架構

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大家好,我是悟空。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/64/64b80533abc1799310f4c6c9e0d11ff4.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文已收錄到我的個人網站:http://www.passjava.cn","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"一、前言","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上一講我們講到了 Eureka 註冊中心的 Server 端有三級緩存來保存註冊信息,可以利用緩存的快速讀取來提高系統性能。我們再來細看下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"一級緩存","attrs":{}},{"type":"text","text":":只讀緩存 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"readOnlyCacheMap","attrs":{}}],"attrs":{}},{"type":"text","text":",數據結構 ConcurrentHashMap。相當於數據庫。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"二級緩存","attrs":{}},{"type":"text","text":":讀寫緩存 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"readOnlyCacheMap","attrs":{}}],"attrs":{}},{"type":"text","text":",Guava Cache。相當於 Redis 主從架構中主節點,既可以進行讀也可以進行寫。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"三級緩存","attrs":{}},{"type":"text","text":":本地註冊表 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"registry","attrs":{}}],"attrs":{}},{"type":"text","text":",數據結構 ConcurentHashMap。相當於 Redis 主從架構的從節點,只負責讀。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"看圖更清晰,如下圖所示:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/7a/7a82fc0efe4cb4c547ef5e5bfdcaa129.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"三種緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另外 ConcurrenthashMap 也是一種 map 結構,也就是以鍵值對的方式進行存儲,如下圖所示:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/91/916d105885dc1b16b8c790c3bac9b415.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Map 結構","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本篇悟空哥會帶着大家來看下 Eureka 的緩存架構是怎麼樣,通過學習這篇,我們也可以借鑑 Eureka 的緩存設計思想,將其運用到項目當中。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"二、引發的幾個思考","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們再來看下 Eureka 源碼,其實不難看懂,下面會做解釋。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f5/f50e333700933f39ef3a3dfd51b0f0dc.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"默認會先從","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"只讀","attrs":{}}],"attrs":{}},{"type":"text","text":"緩存裏面找。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沒有的話,再從","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"讀寫","attrs":{}}],"attrs":{}},{"type":"text","text":"緩存裏面找。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"找到了的話就更新只讀緩存,並返回找到的緩存。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"還找不到的話,就從本地緩存 registry 中加載進來。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"帶來了三個問題:","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(1)三級緩存數據怎麼來的?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(2)緩存數據如何更新的?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(3)緩存如何過期?","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"三、本地緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們先來看下本地緩存 registry,它是一種定義爲 ConcurrentHashMap 的數據結構,之前也詳細講解過。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當客戶端發起註冊請求的時候,就會把註冊信息放到 registry 中。如下代碼所示:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"registry.putIfAbsent(app)\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"putIfAbsent 表示如果存在重複的 key,就不會放入值,如果傳入的 key 對應的 value 已經存在,就返回存在的 value,不進行替換。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"經過 putIfAbsent 操作就把客戶端的註冊信息放到 registry 中了。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/7a/7a82fc0efe4cb4c547ef5e5bfdcaa129.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們再來看下其中的一種緩存結構:讀寫緩存。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"四、讀寫緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讀寫緩存,顧名思義,就是既可以進行讀,也可以進行寫的緩存。讀主要是給只讀緩存來讀取的。寫主要是將緩存更新到自己的 Map 中。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下面分別從寫緩存的原理、寫緩存的源碼、過期時機的原理、過期時機的源碼幾個方面來分別解答。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3.1 寫緩存的原理和源碼","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我開始以爲當我們讀緩存讀不到的時候,就會去數據庫查了。找了半天,沒找到讀數據庫的地方。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然後我就用 IDEA 工具查找 readOnlyCacheMap 被使用的地方,終於讓我找到了。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d2/d22b14add43a396fb442d6000aba8298.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讀寫緩存用的是 Guava Cache工具類,這篇不會深究。簡單來說就是當訪問讀寫緩存時,如果這個 key 在緩存中不存在,則從本地去查,查到後再放回緩存。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然後又實現抽象方法 load(key),這個方法的作用就是當讀寫緩存中沒有,則從本地 registry 緩存中拿。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e0/e06294225dd83245e463c2802bb1ac7d.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讀寫緩存過期的時候其實分兩種:","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"定時過期和實時過期","attrs":{}},{"type":"text","text":"。由於上面的源碼已經定義了定時過期的時間間隔,所以我們先來看定時過期。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3.2 定時過期","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當構建這個讀寫緩存時,就會定義間隔多久過期整個讀寫緩存。如下代碼所示,180 s 會定時過期讀寫緩存。","attrs":{}}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"expireAfterWrite(180s)\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a9/a9130e122a4d31e9b30886a2cb1a510c.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3.3 實時過期","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當有新的服務實例進行","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"註冊或者下線、發生故障","attrs":{}},{"type":"text","text":"時,就會把這個對應的服務實例的緩存給過期掉。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如下圖所示,最上面的是註冊中心,下面三個是服務實例。服務實例發生註冊、下線、發生故障,註冊中心都是可以感知到的,然後就會主動過期讀寫緩存對應的服務實例。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/de/ded3258d2b2da1e4394303456d512176.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3.4 實時過期源碼","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從源碼層面我們再來看下讀寫緩存過期的源碼。調用了 invalidateCache 方法,進行過期。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"文件路徑:com/netflix/eureka/registry/AbstractInstanceRegistry.java","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/7a/7a82fc0efe4cb4c547ef5e5bfdcaa129.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"五、只讀緩存","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"5.1 定時更新","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"只讀緩存 readOnlyCacheMap,有一個定時更新的機制,每隔 30 秒就會更新一次只讀緩存中的某些 key。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/4c/4ca191cd969792c0f70f2b36df0e9fcc.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它其實是遍歷自己的所有註冊信息,然後和讀寫緩存進行比對,如果註冊信息不一致,則替換爲讀寫緩存的數據。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"源碼如下,有一個定時調度任務,每隔 30 秒調度一次。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/de/deb9b755a44c5734eea6f0b599aa80d5.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"5.2 更新","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"另外當客戶端獲取註冊信息時,也會先讀只讀緩存,如果只讀緩存中沒有,則會從讀寫緩存中找,找到後就放到只讀緩存中。如果讀寫緩存中沒有,則從本地註冊表 registry 中加載到讀寫緩存中,然後將註冊表信息返回。","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏大家是否有個疑問:既然這個緩存叫做只讀緩存,怎麼還能被更新,不應該是不變的嗎?","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其實這裏的不變是相對於客戶端來說的,客戶端獲取註冊表信息時,最開始訪問的就是隻讀緩存,類似數據庫或 Redis 的主從架構,主負責讀寫,從負責讀。然後系統內部會把主節點的信息同步給從節點。大家明白了嗎?","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"六、緩存相關配置","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下面我們來看下 Eureka Server 對於緩存有哪些配置呢?","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"6.1 是否開啓只讀緩存","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"eureka.server.useReadOnlyResponseCache","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當客戶端獲取註冊信息時,是否先從只讀緩存獲取。如果爲 false,則直接從讀寫緩存獲取。默認爲 true。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"6.2 定時更新只讀緩存的間隔時間","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"eureka.server.responseCacheUpdateIntervalMs","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"默認每隔 30 秒將讀寫緩存更新的緩存同步到只讀緩存。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"七、緩存帶來的問題","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"三級緩存看似可以帶來性能的提升。但是也會引入其他問題,比如緩存不一致問題。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"只讀緩存每隔 30s 纔會刷新一次,和讀寫緩存會造成數據的不一致,客戶端在 30s 內獲取的註冊表信息是滯後的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當使用 Eureka 集羣時,這種緩存不一致的問題會更明顯,不同的節點之間也會出現只讀緩存的數據不一致,所以 Eureka 只能保證高可用,並不能保證強一致性,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"也就是保證了 AP,不保證 CP","attrs":{}},{"type":"text","text":",另外我們可以選用強一致性的註冊中心,比如 Zookeeper、Nacos,這是後續要講的內容了。","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如何緩解不一致的問題呢?","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(1)在服務端,我們可以設置更新只讀緩存的時間間隔,默認是 30 秒,縮短一點,比如 15 秒,頻率太高,可能對 Eureka 造成性能問題。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(2)服務端,我們也可以考慮關閉從只讀緩存讀註冊表信息,Eureka Client 直接從讀寫緩存讀取。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6c/6c5deabb92f22e7e89688274c7ec07cb.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"八、總結","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/30/30507df444453db018750617e704cddd.webp","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Eureka Server 註冊表三級緩存架構","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本篇學習了 Eureka 註冊中心 Server 端的三層緩存架構,分爲 registry、readOnlyCacheMap、readWriteCacheMap,用來保存服務註冊信息。","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"默認情況下,每隔 30 秒從讀寫緩存將註冊信息更新到只讀緩存。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"默認情況下,客戶端讀取註冊表時,先從只讀緩存讀,如果沒有,則從讀寫緩存中讀取,如果還是沒有,則從本地註冊表 registry 讀取。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"默認情況下,每隔 180 秒定時過期讀寫緩存。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務實例註冊、下線、故障時,會實時過期讀寫緩存。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"引入了多級緩存,也會帶來緩存不一致的問題。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":"br"}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"參考資料: ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"www.passjava.cn ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"《微服務架構深度解析》 ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Eureka 源碼","attrs":{}}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章