從開源自治,到微服務雲化,阿里雲的這款產品給了一劑提升微服務幸福感的良藥

程式碼派就是我發表於2020-07-08

釋出會傳送門

前言

微服務發展至今,因其高內聚、低耦合等特性,以及諸多開源方案帶來的開放性,已成為提升架構效率的最佳實踐之一。當一項技術或一個框架成為事實標準之後,我們會把更多的注意力聚焦在運維效率和應用可用性的持續提升上。相信下面這些場景大家或多或少都遇到過。

場景一,當業務達到一定的規模之後,微服務的數量和單個微服務例項的數就會變的很多,從而導致微服務註冊中心需要管理很多服務地址,同時還需要給所有的上下游提供服務註冊和服務發現的能力。

場景二:釋出是天大的事情,每一次的釋出,都會出現執行到一半的請求中斷掉,上游繼續呼叫已經下線的節點導致報錯的現象。釋出時收到各種報錯,同時還影響使用者的體驗,釋出後又需要修復執行到一半的髒資料。

上述場景還是在新版本沒有任何問題的情況下,如果新版本有問題,則會導致大量業務直接請求到有問題的新版本,輕則修復資料,重則嚴重影響使用者體驗,甚至產生資損。最後不得不每次發版都安排在凌晨兩三點發布,心驚膽顫,睡眠不足,苦不可言。

場景三:大半夜某個服務節點出現異常,上游仍舊不斷地呼叫,出現很多異常和各種報警簡訊。被報警吵醒後,想直接線上上修復,有點難,想保留現場又害怕拖垮整個應用,只好先重啟為上。

但是這只是治標不治本的方式,因為很難復現從而無法有效定位,可能明天又被吵醒,繼續重啟。上述場景還是建立在報警系統比較完善的情況下,如果沒有完善的報警系統,嚴重情況可能整個業務系統都被單機異常拖垮。

場景四:公司業務壯大了,部門組織變複雜後,微服務模組越來越多。我不清楚釋出的服務到底被誰呼叫了,所以我不知道能否安全地下線一個服務。我這個應用的這個介面是個敏感介面,我只希望得到我授權的應用才能呼叫,而不是直接從服務註冊中心得到我的地址就能直接呼叫,但是目前好像還做不到。

面對以上這些場景,可以透過投入更多的開發和運維資源來解決,但對於大部分希望專注於業務開發的企業來說,如果能有一款適合企業自身需求,支援元件化的商業化產品,將會是更好的選擇。

接下來,我們就來詳細剖析下阿里雲微服務MSE是如何解決以上問題的。

一、註冊和配置中心託管

相比基於Zookeeper/Nacos/Eureka來自建註冊中心,MSE 提供了以下這些差異化競爭力。

9989c5b90f96dedb20d3e717592eeed2c54bdb86.jpeg

二、如何降低應用釋出出錯率

什麼是無損下線

傳統的釋出流程中,服務提供者停止再啟動,服務消費者感知到服務提供者節點停止的流程如下:

9989c5b90f96dedb20d3e717592eeed2c54bdb86.jpeg

1、服務釋出前,消費者根據負載均衡規則呼叫服務提供者,業務正常。
2、服務提供者 B 需要釋出新版本,先對其中的一個節點進行操作,首先是停止 Java 程式。
3、服務停止過程,又分為主動登出和被動登出,主動登出是準實時的,被動登出的時間由不同的註冊中心決定,最差的情況會需要 1 分鐘。

如果應用是正常停止,Spring Cloud 和 Dubbo 框架的 Shutdown Hook 能正常被執行,這一步的耗時可以忽略不計。

如果應用是非正常停止,比如直接使用 kill -9 停止,或者 Docker 映象構建的時候 Java 應用不是 1 號程式且沒有把 kill 訊號傳遞給應用。那麼服務提供者不會主動去登出服務節點,而是在超過一段時間後由於心跳超時而被動地被註冊中心摘除。

4、服務註冊中心通知消費者,其中的一個服務提供者節點已下線。包含推送和輪詢兩種方式,推送可以認為是準實時的,輪詢的耗時由服務消費者輪詢間隔決定,最差的情況下需要 1 分鐘。

5、服務消費者重新整理服務列表,感知到服務提供者已經下線了一個節點,這一步對於 Dubbo 框架來說不存在,但是 Spring Cloud 的負載均衡元件 Ribbon 預設的重新整理時間是 30 秒 ,最差情況下需要耗時 30 秒。

6、服務消費者不再呼叫已經下線的節點。

從第 2 步到第 6 步的過程中,Eureka 在最差的情況下需要耗時 2 分鐘,Nacos 在最差的情況下需要耗時 50 秒。在這段時間內,請求都有可能出現問題,所以釋出時會出現各種報錯,同時還影響使用者的體驗,釋出後又需要修復執行到一半的髒資料。最後不得不每次發版都安排在凌晨兩三點發布,心驚膽顫,睡眠不足,苦不可言。

MSE提供的無損下線功能會自動在釋出新版本的時候做如下的增強,我們主要關注綠色部分的資訊:

9989c5b90f96dedb20d3e717592eeed2c54bdb86.jpeg

1、應用在釋出前主動向註冊中心登出應用,並將應用標記為已下線的狀態。

2、在接收到服務消費者請求時,首先會正常處理本次呼叫,並通知服務消費者此節點已下線,服務消費者會立即從呼叫列表刪除此節點。

3、在這之後,服務消費者不再呼叫已經下線的節點。

MSE的無損下線功能,將原來的從原來的 停止程式階段 登出服務變成了 prestop 階段登出服務,將原來的依賴於 註冊中心推送,做到了服務提供者直接通知消費者從呼叫列表中摘除自己。使得下線感知的時間大大減短,從原來的分鐘級別做到準實時,確保您的應用在下線時能做到業務無損。

金絲雀釋出再加一重保障

在普通的新版本釋出場景中,預設情況下請求到各個節點的流量是均勻分佈的。

假設服務提供者有 4 臺,只要某個節點一發布新版本,就會有 25% 的流量打到新版本。如果新版本存在問題,就會影響線上 25% 的流量,輕則修復資料,重則嚴重影響使用者體驗,甚至產生資損。

9989c5b90f96dedb20d3e717592eeed2c54bdb86.jpeg

MSE提供的金絲雀釋出功能,支援使用者在釋出新版本之前就提前配置好金絲雀規則,使得只有符合流量特徵的流量會呼叫到新版本,從而可以精準地控制呼叫到新版本的流量,進行新版本驗證。

9989c5b90f96dedb20d3e717592eeed2c54bdb86.jpeg

在釋出一個新版本的應用的時候,透過一個新的 Deployment 來發布,並在 Deployment 中填寫相應的版本號

新版本啟動之後,預設沒有流量,需要在 MSE 控制檯配置流量規則才有流量進來,可以基於流量百分比進行配置,也可以按照流量特徵進行配置。

配置完成後,Agent 會自動將路由規則推送到服務消費者端,服務消費者會去根據配置好的規則選擇去呼叫新版本或者舊版本。

9989c5b90f96dedb20d3e717592eeed2c54bdb86.jpeg

比如這裡我們配置 user-id 對 100 取模為 20 的會去新版本,那麼 user-id=120 的這個流量就會去新版本。

三、如何避免半夜醒來重啟機器

開源框架有可能被單點異常拖垮整個應用系統

在微服務架構中,當服務提供者的應用例項出現異常時,服務消費者無法及時感知,會影響服務的正常呼叫,進而影響消費者的服務效能甚至可用性。

9989c5b90f96dedb20d3e717592eeed2c54bdb86.jpeg

在上圖的示例場景中,系統包含 4 個應用,A、B、C 和 D,其中應用 A 會分別呼叫應用 B、C 和 D。當應用 B、C 或 D 的某些例項異常時(如圖中應用 B、C 和 D 標識的各有 1個和 2 個異常例項),如果應用 A 無法感知,會導致部分呼叫失敗;如果業務程式碼寫的不夠優雅,有可能影響應用 A 的效能甚至整個系統的可用性。

離群例項摘除給業務系統的穩定性加把鎖

為了保護應用的服務效能和可用性,MSE支援檢測應用例項的可用性並進行動態調整,以保證服務成功呼叫,從而提升業務的穩定性和服務質量。

如下圖所示,您可以在控制檯上對應用 A 進行如下配置,從而保證 A 應用的穩定性。

9989c5b90f96dedb20d3e717592eeed2c54bdb86.jpeg

1、 異常型別,網路異常指的是 IOException,業務異常在 Spring Cloud 框架中指的是返回值 http 狀態碼 為 500 ,Dubbo 框架中指的是返回值中包含 Exception。
2、 QPS 下限,為了避免呼叫次數太少,隨機性較大從而影響判斷的準確性,您可以設定 QPS 的下限,只有 QPS 達到一定值後才進行離群摘除判斷。預設為 1 ,可以配置成 0。
3、 錯誤率下限,如果某臺服務提供者返回值中,錯誤的比例超過了配置的這個值,會被判定成需要被摘除。
4、 摘除例項比例上限,為了避免摘除過多的機器節點,導致剩餘的節點數流量過載,需要配置一個摘除比例的上限,建議不超過 50%。
5、 恢復檢測單位時間,離群節點被摘除的動作是暫時性的,經過單位時間
後,消費者側會對此節點進行檢測。如果節點已經恢復,會將其放回到節點中。如果節點持續被摘除,那麼它被摘除的時間會線性增加到最大值。

基於離群例項摘除功能,您不會因為單機異常在半夜醒來重啟機器,先安心地睡一覺吧,反正業務也不會受影響。醒來之後機器現場也還在,是拿著保留的現場進行分析,還是直接重啟,任君選擇。

四、如何做到對自己的服務胸有成竹

服務查詢一目瞭然

我們熟知的 zookeeper 元件並沒有服務查詢介面,Eureka 和 Nacos 這兩個註冊中心,雖然提供了網頁版的控制檯,但是在控制檯上只能查詢到服務的 IP 和 port 等基本的資訊。

MSE使用者在使用服務查詢時,不僅能夠查詢到應用註冊了哪些服務,對應的 IP 和 port 是什麼,還能查詢到服務包含的具體方法和引數型別,以及直觀地看到服務被其他應用和節點的訂閱情況。

9989c5b90f96dedb20d3e717592eeed2c54bdb86.jpeg

即使部門組織再複雜、微服務模組再多,您也可以清晰地查詢出服務的被呼叫情況,做到心中有數,在梳理服務依賴以及評估影響面的時候可以做到胸有成竹。

精準地控制服務呼叫的許可權

業務發展後,服務還會遇到許可權控制的需求。比如優惠券部門的某個應用,同時包含了優惠券查詢介面 和優惠券發放介面。對於優惠券查詢介面來說,預設公司內部的所有應用都有許可權呼叫的;但優惠券發放介面只有客服和運營部門的某些應用才有許可權呼叫。

如下圖所示,MSE使用者可以對自己的服務進行許可權管理,這裡以 Dubbo 為例,下圖中配置表明,應用 cartservice 釋出的 com.alibabacloud.hipstershop.CartService 服務的 addItemToCart 的方法,只允許 frontend 這個應用呼叫。

9989c5b90f96dedb20d3e717592eeed2c54bdb86.jpeg

除了支援對指定的介面新增鑑權規則之外,服務鑑權也支援對整個應用新增鑑權規則,還支援根據呼叫方 IP 進行鑑權。

精準的許可權管理,可以讓你更好地管理微服務呼叫的許可權,保證業務的合規性,保障資料的安全。

結語

MSE 以元件化的方式來提供微服務能力,客戶既能對應用實現自主可控,還能低門檻的接入註冊中心和配置中心的託管,以及高階的微服務治理能力。據悉,Spring Cloud 和Dubbo近5年的開源版本,均可0程式碼修改就能接入MSE。


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

相關文章