如何輕鬆應對偶發異常

作者:亦盞

在之前的文章中,我們已經介紹瞭如何通過 MSE 提供的無損上下線和全鏈路灰度這兩個功能來消除變更態的風險,相信您已經能夠在變更時得心應手。但是在應用運行過程中突然遇到流量洪峯、黑產刷單、外部依賴故障、慢 SQL 等偶發異常時,您如何能夠繼續輕鬆應對呢?

本文將通過介紹 MSE 微服務治理在三月的最新功能來告訴您答案。文章主要分爲三部分,首先是 MSE 微服務治理的簡介,然後是 MSE 全面消除變更態風險的回顧 ,最後是如何藉助 MSE 微服務治理輕鬆應對線上偶發異常。

MSE 微服務治理簡介

首先看一下微服架構的總覽,相信讀者朋友們對微服務都不陌生。在 JAVA 中比較主流的微服務框架就是 Dubbo 和 Spring Cloud,同時現在也有很多公司採用 Go、Rust 這些語言去構建自己的微服務。下圖中淺綠色的這一部分都是純開源的內容,除了微服務框架本身外,還包含了服務註冊發現、服務配置中心、負載均衡等一系列的組件。

image.png

大家也發現,在微服務實施的過程中,隨着微服務的增多、調用鏈路的複雜化,出問題和故障的可能性都在增加,問題定位的難度也成倍上升。比如說在可觀測領域,需要使用到應用監控、鏈路追蹤、日誌管理等功能,才能放心地將應用部署到線上,以免出現問題無法定位。

更進一步,微服務本身更需要引入微服務治理。在開發態,需要通過服務 mock、服務測試、服務元數據等治理功能去保證微服務的快速迭代;在變更態,需要藉助無損上下線和全鏈路灰度功能去保證發佈時的穩定性,以及業務的連續性;在運行態,微服務可能遇到各式各樣的偶發異常,需要藉助治理功能去實現流量的自愈,保證我們的業務穩定、流暢地運行。很難想象一個線上的微服務應用沒有治理是個什麼場景,可以說是 治理、不生產。

隨着使用微服務架構的公司越來越多,大家也都意識到微服務治理非常重要,但是在實施微服務治理的過程中,大家還是遇到了比較多的痛點和難點。我們總結了一下,企業在實施微服務的過程中遇到的三類問題,分別是穩定、成本和安全。

  1. 首先是穩定的問題
    1. 微服務在發佈的過程中特別容易出現問題,每次發佈都得熬夜以避開業務高峯期,而且還是免不了出現業務中斷。
    2. 當遇到難得的業務爆發式增長時,應用因爲無法承載流量高峯導致整體宕機,錯失了業務爆發的機會。
    3. 在出現一些偶發異常的時候,應用沒有完善的防護和治癒手段,可能會因爲偶發的小異常,不斷的滾雪球,最終去拖垮我們整個集羣和整個服務。
    4. 遇到偶發問題的無法準確定位和徹底解決,只能重啓方式規避,從而使得我們微服務的隱患越積越多,風險越來越大。
  1. 第二是成本的問題
    1. 微服務治理功能在開源沒有完善的解決方案,這個時候可能是需要去招聘大量精通微服務的人才,才能自建一套微服務治理體系,但是也無法覆蓋完整的治理場景。這會使得人力成本非常高。
    2. 引入了微服務之後,基本都會有一些敏捷開發、快速迭代的訴求。在這個過程中,需要維護多套環境以維持一個並行開發迭代的需求,這會使得機器成本非常高。
    3. 傳統的開發模式,當需要引入一個治理功能升級的時候,需要先升級基礎組件,再對所有的應用進行代碼改造,依次發佈才能完成升級,改造的週期長、風險大。這會使得時間成本非常高。
  1. 最後是安全的問題
    1. 經常會有一些開源的框架的安全漏洞被暴露出來,這個時候需要對依賴進行升級以修復 Bug,走一次完整的發佈才能實現,成本高,時效性差。
    2. 零信任安全的解決方案正在被越來越多的公司採用,去保障整體的業務安全。不僅是在流量入口層對業務進行安全的保障,在應用間的內部調用也需要有完整的鑑權和保障機制。

那麼 MSE微服務治理是怎麼去解決這三個問題的?

MSE 的微服務治理基於開源的 OpenSergo 標準實現了無侵入的微服務治理。對於使用者來說升級成本是零,業務是完全無侵入感知的。

目前已經可以做到是五分鐘接入,半小時內就學會完整的使用,保障微服務應用在變更態和運行時的穩定性。因爲 OpenSergo 是全面開源標準,不會有任何的廠商綁定的問題。

image.png

從上圖中可以看出,微服務應用可以通過 Java Agent 或 Sidecar 的方式接入MSE 微服務治理。在接入治理後,可以通過 MSE 微服引擎的控制面配置治理規則的配置。應用收到規則之後會實時生效,及時地保護應用。

全面消除變更態風險的回顧

現在來回顧一下,變更態存在哪些問題,以及 MSE 是如何全面消除變更態風險的。

首先問大家一個問題,當你的代碼沒有問題的時候,是不是在發佈的過程中就一定不會影響到業務? 答案其實是否定的,因爲這個時候可能會遇到無損上下線的問題。

爲什麼會出現無損下線問題?第一個原因是服務消費者無法實時感知到服務提供者已經下線了,仍舊會去調用一個已經下線的地址,從而出現一個影響業務的報錯。同時服務提供者也可能會在請求處理到一半的時候就直接停止了,從而導致業務報錯,甚至出現數據不一致的問題。

爲什麼會出現無損上線的問題?一個新啓動的節點,有可能在還沒完全啓動前就註冊到註冊中心了,進而導致這時候過來的流量無法被正確處理導致報錯;另一種情況是,雖然應用啓動完成了,但是還沒有處理大流量的能力,可能直接被大流量壓垮,需要先進行預熱,才能處理大流量的請求。除此之外,目前 K8s 的普及率已經非常高了,如果微服務的生命週期沒有與 K8s 生命週期做一個的 readiness 對齊的話,發佈過程也容易出現無損上線問題。

當然更普遍的情況是,誰都不敢拍着胸脯保證我的代碼沒有問題。 如果沒有穩定的灰度機制,對只有兩個節點的應用來說,發佈一臺就會影響 50% 的業務。發現 bug 之後需要回顧,可怕的是回滾的速度還非常慢,甚至回滾的時候還出現了更大的問題。

那麼 MSE 是如何去解決這兩個問題的。首先我們看一下這個無損下線的這個問題。對於一個已經接入了MSE 微服務治理的應用,無損下線功能是默認開啓的,我們可以在 MSE 的控制檯中看到無損下線的完整的流程。

image.png

  1. 首先在無損下線開始時,sc-B 這個服務的提供者 10.0.0.242 會提前向註冊中心發起註銷動作。
  2. 註銷之後,10.0.0.242 會去主動去通知它的服務消費者當前節點已下線。上圖中的例子,服務 sc-B 的消費者 10.0.0.248 和 10.0.0.220 這兩個消費者收到了下線通知。
  3. 10.0.0.248 和 10.0.0.220 在收到下線通知後,都會把 10.0.0.242 的地址維護在 offlineServerIp 列表中,並且找到 sc-B 對應的調用列表,在調用列表中移除 10.0.0.242 這個 IP
  4. 同時,10.0.0.242 在停止的過程中會做一個自適應的等待,確保所有在途請求都處理完畢才停止應用。

我們再看一下這個無損上線的這個問題。對於一個已經接入了 MSE 微服務治理的應用,可以通過控制檯開啓無損上線功能,開啓後,我們可以在 MSE 的控制檯中看到無損上線的完整的流程。

image.png

從上圖中我們可以看到,應用配置的延遲註冊時間是 10S,預熱時間是 120S,預熱曲線是擬合二次曲線。根據 QPS 數據可以看到,應用在註冊完成之後纔有流量進入,同時在預熱開始後 120S 內,流量是一個緩慢上升的過程,直到預熱結束之後,流量纔開始進入平穩的狀態。

看完了在代碼沒問題的情況下如何保證變更態的穩定性,我們在看看當代碼可能存在問題的時候,如何保障變更態的穩定性。

拿一個簡單的架構作爲例子,微服務的整體調用鏈路是網關調用 A,A 調用 B ,B 再調用 C 這麼一個鏈路。某次迭代中,有個特性的修改需要同時修改 A 和 C 這兩個應用。

image.png

在發佈的過程中,需要通過全鏈路灰度發佈來驗證 A 的新版本和 C 的新版本的正確性。假設 x-user-id 爲 120 的用戶是我們一個不那麼重要的用戶。那麼我們可以配置只有 x-user-id 爲 120 的這一個用戶,他纔會訪問新版本。

在具體的調用中,網關會先訪問 A 的灰度版本,A 在調用 B 的時候發現 B 沒有一個灰度的版本,所以只是 fall back 到 B 的基線版本。但是 B 在調用 C 的時候,還是記住了 x-user-id 爲 120 的流量屬於一個灰度流量。同時又發現 C 存在灰度節點,流量還是會重新回到 C 的灰度節點。

image.png

如上圖所示,可以通過 MSE 全鏈路灰度控制新版本的影響面。將參與到全鏈路灰度的應用添加到泳道組後,配置如上圖所示的規則,只有 x-user-id 爲 120 的這個用戶他纔會被路由到新版本。也就是說即使這個新版本問題再大,那只是這一個用戶會受到影響。同時做一個回滾的動作也是非常方便的,只需要把灰度規則關閉或者刪除即可,就不會有流量被路由到新版版本。經過灰度的謹慎驗證後,可以視情況繼續擴大灰度的影響面,或者直接全量發佈,從而實現安全的版本變更。

剛纔我們也提到過,全鏈路灰度其實是一個非常複雜的過程,除了 RPC 的灰度外,還包含了前端灰度、消息灰度、異步任務灰度、數據庫灰度等場景,這些場景 MSE 都做了一些探索和支持。以消息灰度爲例, MSE 已經完整地支持了 RocketMQ 的灰度,實現了全鏈路灰度的閉環,是一個久經生產考驗的全鏈路灰度。

image.png

以上是 MSE 全面消除變更態風險的回顧。

如何輕鬆應對偶發異常

在回顧了一下 MSE 是如何做到全面消除變更態風險之後。我們來看一下 MSE 微服務治理在三月份新上線的這些功能,如何幫助大家輕鬆應對偶發異常。

我們做了大致的總結和歸類,將偶發異常的情況分爲了兩部分:異常流量和不穩定服務依賴。

image.png

接下來我們將面向這兩個大類下五個小類的場景,來闡述如何藉助 MSE 微服務治理三月份發佈的新功能去解決這些偶發異常的。

接口限流

首先我們看一下激增流量這一塊。拿一個具體的場景來說,業務方精心準備了一個大促活動,活動非常火爆,在活動開始的一瞬間,遠遠超過系統承載預期的用戶進來搶購秒殺,如果沒有微服務治理能力,服務可能由於扛不住流量直接被打掛,甚至在重啓的過程還不斷被打掛。精心準備的活動由於系統宕機導致效果非常差,在遇到難得的業務爆發式增長機會時,卻因爲應用的宕機錯失了爆發的機會。

在這個場景下,可以藉助 MSE 的流控能力對關鍵接口配置流控規則保護應用整體的可用性。只讓容量範圍內的請求被處理,超出容量範圍外的請求被拒絕,相當於這是一個安全氣囊的作用。

image.png

如上圖所示, /a 這個接口是我們應用的關鍵接口,我們識別到單機閾值是 200 後,配置上流控防護規則,使得這個關鍵接口最大的通過 QPS 是 200,超出閾值的流量會直接被拒絕,從而保護應用整體的可用性。

精準限流

接下來我們再看一下精準限流,拿一個具體的場景來說,由於在配置優惠活動的時候沒有配置好最大次數,或者存在規則上的漏洞。在被黑產發現後不斷地進行在刷單,業務損失嚴重。在這個場景下,我們可以藉助 MSE 的精準限流能力實現防黑產刷單。

MSE 的精準限流可以在 API 的維度基礎上,基於流量的特徵值來進行限流,比如根據調用端的 IP,參數中的某一個參數的值,或者說 HTTP 請求裏 header 的特徵等。

image.png

如上圖所示,當我們識別到黑產用戶的特徵之後,可以根據 header 裏面 key 爲 user-id 的值來進行精準的業務限流,這裏配置的規則爲每天只能通過一次,也就意味着黑產流量被識別到之後,一天內超出一次的調用都會被拒絕,這樣就能有效地防止黑產刷單保護業務。

併發隔離

第三部分是併發隔離,拿一個具體的場景來說,假設我們的應用依賴了一個第三方的支付渠道,但是因爲渠道本身的原因出現了大量的慢調用,進而導致了應用全部的線程池都被調用該支付渠道的調用佔滿了,沒有線程去處理其他正常的業務流程。而且這個第三方的支付其實只是我們其中的一個支付渠道。我們其他的支付渠道都是正常的。

MSE 可以對應用作爲客戶端的流量進行併發隔離,限制同時調用這個第三方支付渠道的最大併發數,從而留下充足的資源來處理正常的業務流量。

image.png

如上圖所示,我們配置了併發數閾值是 5,每個應用節點最多同時存在 5個併發去調用第三方支付服務,當調用數超過了 5 的時候,請求在發起前就會直接被拒絕。通過併發隔離,把不穩定的支付渠道隔離到有限的影響面,而不會擠佔其他正常支付渠道的資源,這樣來保障我們一個業務的穩定性。

SQL 防護

第四部分是 SQL 防護,拿一個具體的場景來說,應用更新後出現了慢 SQL 的語句,處理的時間比較長的,這個時候需要快速定位慢 SQL ,然後防止我們這個應用去被這個慢 SQL 拖垮了。或者在項目的初期可能沒有對這個 SQL 的性能做一個很好的考量,然後隨着業務的發展,業務量級的增加,然後導致線上遺留老 SQL 逐漸腐化,成爲了一個慢 SQL。

MSE 的數據庫治理功能,可以自動統計應用的 SQL語句,以及 SQL 的 QPS、平均耗時 和最大併發等數據,並針對於 SQL 進行一個防護。

image.png

如上圖所示,在平均耗時中找到慢 SQL,點擊右邊的 SQL 防護按鈕,通過配置併發隔離規則來進行保護應用不被慢 SQL 拖垮。

服務熔斷

最後我們再來看一下服務熔斷。拿一個具體的場景來說,在業務高峯期查詢積分服務達到性能瓶頸,導致響應速度慢、報錯增多。但是它並不是一個關鍵的服務,這時不能因爲無法查詢積分餘額而導致整個流程都無法進行。正確的邏輯應該是積分餘額暫時不顯示,但是除此之外其他主流程都能正常完成。

MSE 的服務熔斷功能,可以很好地解決上述的問題。MSE 支持通過慢調用的比例,或者錯誤數去衡量一個服務是否處於正常狀態,當識別到服務已經不正常的時候就自動觸發熔斷。熔斷後消費者不會再去調用出問題的服務了,而是直接返回 Mock 值。

image.png

如上圖所示,配置當異常比例超過 80% 的時候自動觸發熔斷,不再去調用不正常的服務。一方面消費者不再去調用不正常的弱依賴服務,不會因爲弱依賴的問題導致主流程不正常。另一方面,熔斷也給了不穩定的下游一些喘息的時間,讓它有機會去恢復。

我們最後再來總結一下 MSE 微服治理是如何助您輕鬆應對線上偶發異常的,針對我們剛纔總結的這五類場景:

  1. 當遇到激增流量的時候,我們應該使用接口限流。
  2. 當我們遇到黑產刷單等問題的時候,我們應該使用精準限流。
  3. 當第三方服務不響應,佔滿線程池的時候,我們應該使用併發隔離。
  4. 當應用存在慢 SQL 的時候,我們應該使用 SQL 防護。
  5. 當應用的弱依賴出現異常,影響我們核心業務流程的時候,我們應該使用服務熔斷。

通過這五個功能,MSE 微服務治理可以助您去輕鬆去應對上述場景的一些偶發異常,後續 MSE 也會持續不斷地去探索和拓展更多場景,更全面地保障您應用的運行時的穩定性。

結語

MSE 微服務治理致力於幫用戶低成本構建安全、穩定的微服務。由於篇幅原因,更多的功能就不在這裏給大家詳細介紹了,關於 MSE 更多的詳情,讀者可以通過查看 MSE 幫助文檔的瞭解詳情。

MSE 幫助文檔:

https://help.aliyun.com/document_detail/126761.html

歡迎感興趣的同學掃描下方二維碼加入釘釘交流羣,一起參與探討交流。

image.png

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