1. 程式人生 > >微服務高可用方案

微服務高可用方案

微服務高可用方案

一、微服務的高可用

在註冊中心、配置中心高可用方案之前,瞭解一下注冊中心的工作原理,下面分為兩個部分來解釋,一是註冊中心和各個微服務的登錄檔的獲取與同步,二是註冊中心如何去維護登錄檔。

1.1、登錄檔的獲取與同步

Eureka Server和Eureka Client之間的關係,通過登錄檔來維護,而登錄檔的通過Eureka Server集中化管理,每個Client在本地進行登錄檔的快取,通過週期性的任務拉取最新的登錄檔資訊。簡單的示例圖如下。

img

根據上圖所展示的流程,可以瞭解到註冊中心與微服務之間的基本聯絡的流程:

1.服務A啟動時,向Eureka Server註冊自己的相關資訊

2.當服務B向Eureka Server拉取最新的登錄檔時,就可以拿到服務A的一臺機器註冊資訊

3.服務A的另外兩臺機器再去註冊,服務B 30s後再次去拉取時,就會得到服務A的三臺機器的註冊資訊

4.服務A、每30s向Eureka Server傳送一次心跳資訊,表明自己的註冊資訊還是有效的

以上是註冊中心與微服務之間互動的大體流程,在具體的實踐中,Eureka Server會提供多級快取,其中的登錄檔的資訊的獲取與同步,又會有細微的差別。

1.Eureka Server的登錄檔直接基於純記憶體,即在記憶體裡維護了一個數據結構。

2.各個服務的註冊、服務下線、服務故障,全部會在記憶體裡維護和更新這個登錄檔。

3.各個服務每隔30秒拉取登錄檔的時候,Eureka Server就是直接提供記憶體裡儲存的有變化的登錄檔資料給他們就可以了。

4.同樣,每隔30秒發起心跳時,也是在這個純記憶體的Map資料結構裡更新心跳時間。

Eureka Server的登錄檔是純記憶體處理的,因此處理速度會很快,同時提供 readWriteCacheMap 和 readOnlyCacheMap 做快取,保障了頻繁讀寫不會衝突。示意圖如下。

img

上圖介紹了Eureka Server多級快取的工作原理:

1.當第一臺服務A註冊時,它的註冊資訊會更新到記憶體的登錄檔中,如果 readWriteCacheMap 中有相應的資訊,則過期掉,如果沒有則不做操作

2.當服務B去拉取登錄檔資訊時,先找 readOnlyCacheMap ,沒有再找 readWriteCacheMap ,再沒有就去記憶體的登錄檔查詢註冊資訊,查到就更新到 readWriteCacheMap 中,返回給服務B,服務B的登錄檔中,就會有一臺服務A的機器註冊資訊

3.readOnlyCacheMap 和 readWriteCacheMap 之間的同步是有一個後臺的定時任務,每隔30s去同步一次,快取同步任務

4.第二臺服務A註冊時,更新記憶體的登錄檔,同時把 readWriteCacheMap 過期掉

5.在快取同步任務執行之前服務B去拉取登錄檔時,都是從 readOnlyCacheMap 中拿到資料,新的登錄檔的資訊,不會被服務B拿到

6.30s後,快取同步任務會同步 readWriteCacheMap 和 readOnlyCacheMap 中的資料,把readOnlyCacheMap 中的登錄檔過期掉,這時服務B就會找 readWriteCacheMap 拿資料,readWriteCacheMap 從記憶體中拿到資料後快取,返回給服務B,服務B的登錄檔中,就會有兩臺服務A的機器註冊資訊

7.在下一個30s,快取同步任務把 readWriteCacheMap 同步到 readOnlyCacheMap 之前, readOnlyCacheMap 沒有第二臺服務A的註冊快取,因此都是從 readWriteCacheMap 中取到最新資料

注:

readOnlyCacheMap 快取更新的定時器時間間隔,預設為30秒

readWriteCacheMap 快取過期時間,預設為 180 秒

由以上流程說明可知,Eureka Server採取了多級快取策略,同時最新的登錄檔生效有30s的時延。多級快取機制的優點是什麼:

1.儘可能保證了記憶體登錄檔資料不會出現頻繁的讀寫衝突問題。

2.並且進一步保證對Eureka Server的大量請求,都是快速從純記憶體走,效能極高。

1.2、註冊中心維護微服務的登錄檔

Eureka Client與登錄檔相關的行為如下所示:

1.服務註冊(Registry)——初始化時執行一次,向服務端註冊自己服務例項節點資訊包括ip、埠、例項名等,基於POST請求。

2.服務續約(renew)——預設每隔30s向服務端PUT一次,保證當前服務節點狀態資訊實時更新,不被服務端失效剔除。

3.更新已經註冊服務列表(fetchRegistry)——預設每隔30s從服務端GET一次增量版本資訊,然後和本地比較併合並,保證本地能獲取到其他節點最新註冊資訊。

4.服務下線(cancel)——在服務shutdown的時候,需要及時通知服務端把自己剔除,以避免客戶端呼叫已經下線的服務。

Eureka Client是通過Jersey Client基於Http協議與Eureka Server互動來註冊服務、續約服務、取消服務、服務查詢等。同時,Server端還會維護一份服務例項清單,並每隔90s對未續約的例項進行失效剔除。

Eureka Server有一個自我保護機制,當網路發生故障時,客戶端與服務端不通,這是需要啟動Eureka Server的自我保護機制,這樣不會剔除服務,當網路恢復時,退出自我保護。自我保護有兩個引數,最後一分鐘收到的心跳數(Renews (last min))、期望收到的心跳數(Renews threshold),當Renews threshold > Renews (last min) 時,進入自我保護模式。

Renews (last min) = 例項數 * 2 #例項數算上Eureka Server自注冊服務

Renews threshold = Renews (last min) * 0.85 # 0.85可配置

下圖的註冊中有10個例項:

img

推薦多個Eureka Server部署時,開啟自我保護

eureka.client.register-with-eureka = true

1.3、分散式註冊中心

瞭解了註冊中心的工作原理,下面開始研究分散式服務,多註冊中心、多服務例項的情況。

當微服務僅向一臺註冊中心註冊時,當這個註冊中心發生故障時,新服務無法繼續註冊上去,舊服務的註冊資訊,快取在其他註冊中心和客戶端中,依舊可以使用,當重啟之後,無法向註冊中心註冊,也是無法使用的。

因此構建高可用的註冊中心時,需要交叉註冊,每個註冊中心既當服務端,又當客戶端,向其他註冊中心註冊自己,同時微服務需要向每個註冊中心進行註冊,由註冊中心自己過濾互備,防止單個註冊中心故障而導致只往它上面註冊微服務重啟後不可用。示意圖如下所示。

img

目前註冊中心與配置中心集中在一起,可拆可不拆,對整體影響不大,拆分是為了註冊中心和配置中心相互間不影響。gitlab部署在某一臺機器上,所有config共用,由於gitlab的原因,導致config的分散式存在單點故障的隱患。每個config分別用獨立的gitlab,又給運維帶來極大的不便。後期採用apollo,用資料庫儲存配置,利用資料庫的分散式優勢替代gitlab,來解決單點故障的問題。

1.4、註冊中心壓測

根據壓測調研,8核4G的Eureka Server在處理1000個服務例項時,沒有任何壓力,在預設情況下,可以處理7000個例項,超出的會超時報錯,在修改tomcat的配置之後,最多可以承載8000例項,此時CPU基本滿載。

升級注意事項:

1、Eureka Server之間相互註冊,Eureka Client需要在每個Server上都註冊一邊

2、Eureka Server開啟自我保護

3、Eureka Client的例項數不超過1000個

參考:

[1] https://www.jianshu.com/p/ae4f0c8b8135

[2] https://www.cnblogs.com/xishuai/p/spring-cloud-eureka-safe.html

[3] http://sprin