程式設計師筆記|API閘道器如何實現對服務下線實時感知

宜信技術學院發表於2019-06-05

上篇文章 《Eureka 快取機制》 介紹了Eureka的快取機制,相信大家對Eureka 有了進一步的瞭解,本文將詳細介紹API閘道器如何實現服務下線的實時感知。

一、前言

在基於雲的微服務應用中,服務例項的網路位置都是動態分配的。而且由於自動伸縮、故障和升級,服務例項會經常動態改變。因此,客戶端程式碼需要使用更加複雜的服務發現機制。

目前服務發現主要有兩種模式:客戶端發現和服務端發現。

  • 服務端發現:客戶端透過負載均衡器向服務註冊中心發起請求,負載均衡器查詢服務註冊中心,將每個請求路由到可用的服務例項上。

  • 客戶端發現:客戶端負責決定可用服務例項的網路地址,並且在叢集中對請求負載均衡, 客戶端訪問服務登記表,也就是一個可用服務的資料庫,然後客戶端使用一種負載均衡演算法選擇一個可用的服務例項然後發起請求。

客戶端發現相對於服務端發現最大的區別是:客戶端知道(快取)可用服務登錄檔資訊。如果Client端快取沒能從服務端及時更新的話,可能出現Client 與 服務端快取資料不一致的情況。

二、閘道器與Eureka結合使用

Netflix OSS 提供了一個客戶端服務發現的好例子。Eureka Server 為註冊中心,Zuul 相對於Eureka Server來說是Eureka Client,Zuul 會把 Eureka Server 端服務列表快取到本地,並以定時任務的形式更新服務列表,同時zuul透過本地列表發現其它服務,使用Ribbon實現客戶端負載均衡。

1.jpg

正常情況下,呼叫方對閘道器發起請求即刻能得到響應。但是當對生產者做縮容、下線、升級的情況下,由於Eureka這種多級快取的設計結構和定時更新的機制,LoadBalance 端的服務列表B存在更新不及時的情況(由上篇文章 《Eureka 快取機制》 可知,服務消費者最長感知時間將無限趨近240s),如果這時消費者對閘道器發起請求,LoadBalance 會對一個已經不存在的服務發起請求,請求是會超時的。

三、解決方案

3.1 實現思路

生產者下線後,最先得到感知的是 Eureka Server 中的 readWriteCacheMap,最後得到感知的是閘道器核心中的 LoadBalance。但是 loadBalance 對生產者的發現是在 loadBalance 本地維護的列表中。 

所以要想達到閘道器對生產者下線的實時感知,可以這樣做:首先生產者或者部署平臺主動通知 Eureka Server, 然後跳過 Eureka 多級快取之間的更新時間,直接通知 Zuul 中的 Eureka Client,最後將 Eureka Client 中的服務列表更新到 Ribbon 中。

但是如果下線通知的邏輯程式碼放在生產者中,會造成程式碼汙染、語言差異等問題。

借用一句名言:

“電腦科學領域的任何問題都可以透過增加一個間接的中間層來解決” 

2.png

Gateway-SynchSpeed 相當於一個代理服務,它對外提供REST API來負責響應呼叫方的下線請求,同時會將生產者的狀態同步到 Eureka Server 和 閘道器核心,起著 狀態同步 和 軟事物 的作用。

思路 :在生產者做  縮容、下線、升級  前,spider 平臺(spider為容器管理平臺)會主動通知 Gateway-SynchSpeed 某個生產者的某個例項要下線了,然後 Gateway-SynchSpeed 會通知 Eureka Server 生產者的某個例項下線了;如果Eureka Server 下線成功,Gateway-SynchSpeed 會直接通知 閘道器核心。

設計特點

  • 無侵入性、方便使用。不用關心呼叫方的基於何種語言實現,呼叫者只要對 Gateway-SynchSpeed 發起一個http rest請求即可,真正的實現邏輯不用侵入到呼叫方而是交給這個代理來實現。

  • 原子性。呼叫方先在Eureka Server下線,然後在所有相關閘道器核心中下線為最小工作執行單元,Gateway-SynchSpeed 相當於一個"軟事物",保證服務下線的某種程度上原子特性。

3.2 實現步驟

3.jpg

步驟說明

  • 第一步:在生產者做  縮容、下線、升級  前,spider平臺會以http請求的形式通知到 Gateway-SynchSpeed 服務,通知的粒度為服務例項所在的容器IP。

  • 第二步:Gateway-SynchSpeed 接受到請求後,先校驗IP的可用性,然後通知Eureka Server。

  • 第三步:Eureka Server 將 Producer 置為失效狀態,並返回處理結果(Eureka 下線形式分為兩種,一種是直接從服務註冊列表直接剔除,第二種是狀態下線,即是將 Producer 的狀態置為 OUT_OF_SERVICE 。 如果是以第一種形式下線,Spider平臺發出下線請求後,不能保證Producer程式立刻被kill,如果這期間 Producer 還有心跳同步到 Eureka Server,服務會重新註冊到 Eureka Server)。

  • 第四步:Gateway-SynchSpeed 得到上一步結果,如果結果為成功,則執行下一步;反之,則停止。

  • 第五步:Gateway-SynchSpeed 為Eureka Client。Gateway-SynchSpeed 透過 IP 到本地服務註冊列表中得到 Producer 的 Application-Name。

  • 第六步:Gateway-SynchSpeed 透過 Application-Name 到閘道器核心庫中查詢所有與下線服務相關的  閘道器組名字

  • 第七步:Gateway-SynchSpeed 透過  閘道器組名字  到本地服務列表中查詢閘道器組下所有的服務地址 ipAddress(ip : port)。

  • 第八步:Gateway-SynchSpeed 非同步通知所有相關閘道器節點。

  • 第九步:Gateway-Core 收到通知後,對 Producer 做狀態下線,同時記錄所有狀態下線成功的例項資訊到快取 DownServiceCache 中。

  • 第十步:Gateway-Core 更新本地 Ribbon 服務列表。

四、補償機制

Eureka 提供了一種安全保護機制。Eureka Client 從 Eureka Server 更新服務列表前,會校驗相關Hash值是否改變( Client 服務列表被修改,hash值會改變),如果改變,更新方式會從增量更新變成全量更新,(由 《Eureka 快取機制》 可知這30s內 readOnlyCacheMap 和 readWriteCacheMap 的資料可能存在差異),如果Client端快取列表被readOnlyCacheMap 覆蓋,最終會導致 Ribbon 端服務列表與 readWriteCacheMap 資料不一致。

針對 Eureka 這種機制,引入監聽器 EurekaEventListener 作為補償機制,它會監聽 Eureka Client 全量拉取事件,對於快取中未超過30s的服務,將其狀態重新設定成  OUT_OF_SERVICE  。

五、API安全設計

考慮到系統的安全性問題,如果被人惡意訪問,可能會使生產者在Eureka Server中無故下線,導致消費者無法透過 Eureka Server 來發現生產者。

使用黑白名單做安全過濾,基本流程如下:

  • 對 Gateway-Synchspeed 中設定白名單網段(IP網段)

  • 在 Gateway-Synchspeed 加入過濾器,對下線請求方進行IP校驗,如果請求端IP在網段中,則放行;反之,過濾。

六、日誌回溯

由於 Gateway-SynchSpeed 和 Gateway-Core 是部署在 Docker 容器中,如果容器重啟,會導致日誌檔案全部丟失。所以需要將 Gateway-SynchSpeed 和 Gateway-Core 中相關日誌寫入到 Elasticsearch ,最終由 Kibana 負責查詢 Elasticsearch 的資料並以視覺化的方式展現。

七、程式碼片段展示

Gateway-SynchSpeed 做狀態同步

5.jpg

EurekaEventListener 處理快取資料

6.jpg

八、 補充說明

目前閘道器實現對服務下線的實時感知中,使用的 Zuul 和 Eureka 版本為 Spring Cloud Zuul 1.3.6.RELEASE 、Spring Cloud Eureka 1.4.4.RELEASE。

目前閘道器實現的是對閘道器下游服務的實時感知,而且需滿足以下條件:

  • 生產者需部署在 kubernetes 容器管理平臺

  • 生產者做正常的 下線、升級或者縮容 操作。如果是由於容器資源不足,導致服務異常當機等非正常下線,不支援。

閘道器服務下線實時感知是閘道器對業務方提供的一種可選的解決方案,在 spider 平臺中預設是沒有開啟此功能,是否開啟此功能由業務方根據本身系統要求決定,具體如何配置可參考  API閘道器接入指南  中 《閘道器實時感知在spider上配置文件說明》。

作者:謝國輝

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69918724/viewspace-2646802/,如需轉載,請註明出處,否則將追究法律責任。

相關文章