通過降級提高系統的可用性

一. 背景

    導致系統服務不可用的有諸多因素,大多數可以由外到內歸結爲以下幾種:

    1、高併發流量;

    2、系統所依賴的第三方服務(數據庫、緩存、接口等);

    3、系統軟件中的bug和運行過程中的不穩定因素;

    4、運行系統的硬件故障。

    對於硬件故障導致的系統不可用,可以在負載均衡器中將該節點摘除,使流量都能在剩餘節點中得到正常處理。本文中主要探討在應用系統之中實現上述前三種情況的判定以及降級方式。

二. 高併發流量

    對於一個應用系統來說一定會有極限請求數,如果超了該閥值則系統就會不響應用戶請求或響應的非常慢。以tomcat爲例,有最大連接數參數maxConnections,超出之後會拒絕連接。對於實際需求來說,往往需要根據不同的業務接口請求採用多種不同的判斷超過閾值並限流的方式,並且對超出閾值的流量進行降級處理,使服務保持可用。

    例如:設定閾值爲某一個接口同時能夠處理的最大請求數,這時可以使用Java中的AtomicLong進行當前請求數的記錄並對本次請求進行判斷,超出該數目即可對本次請求進行降級邏輯處理。

=================================

try {
    if(atomic.incrementAndGet() > 最大請求數) {
        //降級處理邏輯
    }
    //處理請求
} finally {
    atomic.decrementAndGet();
}

=================================

    此外還可使用令牌桶算法和漏桶算法進行限流,其中的某些實現可以允許不同程度的突發流量、整形爲平滑流量或控制時間窗口內的流量,以應對不同的業務場景。

    降級處理邏輯可以有以下幾種形式:

    1、使用兜底數據或默認數據;

    2、選取較爲重要的請求參數對正常處理請求的結果進行緩存,降級時讀取緩存數據;

    3、使用一個相對於正常請求處理邏輯耗時較少的簡化處理邏輯;

    其目的是要保證用戶仍然能獲取到有損服務而不是沒有服務,同時降級邏輯首先保證的是快速響應並佔用較少的系統資源(主要表現在cpu以及io),保證整個服務仍然可用,在此基礎上儘可能的提高降級處理邏輯的服務質量。

三. 第三方服務

    第三方服務的可用性可以通過以下兩個方面來判斷:

    1、 服務響應時間對系統可用性造成的影響;

    2、 服務返回結果的可用性;

    根據系統本身的響應時間、qps以及各模塊的處理時間,來估算出該服務響應時間的閾值。調用服務超時後進行截斷並判斷本次服務不可用,進行降級處理。在後續使用中不斷對超時時間進行修正,在不影響系統性能和響應時間的前提下,保證儘可能多的請求不被超時截斷。

    正常接收到響應後,可以利用現有解析響應結果的邏輯來進行格式正確性的校驗。解析出現異常情況時判斷本次服務不可用並進行降級處理。在後續使用中根據實際需求可以對數據內容加一部分正確性校驗。   

 

圖1 第三方服務可用狀態判斷流程示意圖

    在實際使用中,第三方服務的不可用往往會持續一段時間,在這種狀態下每次都調用服務並進行可用性判斷會影響系統本身的性能,尤其是在第三方服務大量超時的情況下。因此可以採用圖1中的服務可用狀態判斷流程。要點如下:

    1、“服務調用”中,包含了上文中所述的單次請求的可用性判斷以及不可用時的降級處理。同時進行該服務調用次數和異常數的記錄。

    2、“更新服務可用狀態”中,爲了減少個別請求異常引起的誤判以及系統性能損耗,服務可用狀態檢查在滿足一定條件下才會被觸發,例如:與上一次檢查時間點的間隔以及最少調用次數的雙重限制。滿足條件後根據異常率(異常數/調用次數)判斷和更新服務可用狀態,並將調用數、異常數清0,同時記錄該時間點以備下一次檢查使用。檢查間隔、最少調用次數、判定不可用的最小異常率等都可設爲參數並根據後續使用情況不斷調整。

    3、“本次請求是否作爲探測”中,當服務狀態不可用時,仍然保留一部分流量進行探測,以便在服務正常後,能夠自動且快速的恢復成可用狀態。爲了達成這個目的,需要設定適當的流量比例,對服務狀態不可用時的請求進行分流。

    降級時處理邏輯可以有以下幾種形式:

    1、對於必需的服務,可以構造默認數據並在降級時使用;

    2對於非必需服務,即不會影響系統功能和正常使用,只會影響系統效果時,可以在系統中進行服務不可用時的兼容處理;

    3、對於服務數據並非實時處理的需要,而是定時更新的情況,可以選擇不進行更新,繼續使用先前獲取的有效數據。

四. 系統自身bug及不穩定因素

    系統本身可能會包含很多不穩定因素,在某些處理邏輯或長時間運行的情況下會導致服務不可用,例如:內存泄漏、死循環、線程阻塞、線程定時創建但沒有回收等。

    針對以上情況,判斷降級相對前兩種情況相對複雜,同時在系統自身bug導致異常時,系統中的降級邏輯可能不會正常工作。因此建議降級的粒度細化到核心的業務類和方法,同時實行手動降級和自動降級相結合的方式。

    自動降級:常用的判斷參數有線程數、處理時間、結果有效性等。同時可以使用單獨的應用心跳檢查系統接口的可用性,並通過系統特定接口設置是否降級。

    手動降級:在人工發現系統不可用後,手動進行切換。在應用層,可以通過系統特定接口來切換;在接入層,可以通過nginx等代理服務器的配置來切換。

    降級時處理邏輯可以有以下幾種形式:

    1、系統應用中使用兜底數據或默認數據,適用於自動降級;

    2、在nginx等代理服務器中切換到默認頁面,適用於自動降級不可用時的手動降級;

    3、使用上一版本或穩定的邏輯,適用於新的不穩定的邏輯上線時。

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