微服務 - 如何進行服務限流和熔斷

1、服務雪崩

​微服務架構是將單個應用程序被劃分紅各類小而鏈接的服務,每個服務完成一個單一的業務功能。相對於傳統的單體服務,微服務具備隔離性、技術異構性、可擴展性以及簡化部署等優勢。一般一個應用由多個微服務組成,微服務之間的數據交互須要經過遠過程調用的方式完成。html

​下圖是一個微服務之間互相調用的場景:java

​微服務A調用微服務B、C和D,微服務C又調用微服務E。假設某一時刻,微服務E變爲不可用。微服務C須要等待微服務E返回結果,因而請求就會逐漸堆積在微服務C,造成阻塞。隨着微服務C堆積的請求不斷增長,微服務A也會隨之慢慢阻塞。由於服務器所能支撐的併發數有限,因此最終會耗盡服務器資源,從而致使調用鏈條上更多的微服務不可用,造成雪崩效應。這種由一個服務崩潰致使整條服務鏈崩潰的狀況,咱們就稱之爲服務雪崩。git

​ 在微服務架構中,一般有兩種狀況會致使服務雪崩:github

  1. 突發性的訪問量劇增,超出了服務處理極限算法

  2. 調用鏈條上某個服務出現故障或者響應慢(延遲)後端

    針對以上這兩種狀況,產生了對應的解決方案:服務限流和服務熔斷。api

2、 服務限流

​ 服務限流是指在必定時間段內限制服務的請求量以保護系統,主要用於防止突發流量而致使的服務崩潰,好比秒殺、搶購、雙十一等場景,也能夠用於安全目的,好比應對外部暴力攻擊。安全

​ 經常使用的限流算法有如下幾種:服務器

  • 計數器算法網絡

    ​ 經過維護一個內部計數器,對一段時間的服務請求進行累計,判斷計數器是否達到預先設定的閾值。若是沒有達到閾值,就容許請求經過,而且計數器加1;若是達到閾值,則拒絕服務,拋棄請求。進入下一個計時週期後,計數器清零,從新計數。

    ​ 計數器算法是限流算法中最簡單的算法,缺點是有突刺現象,不只請求經過的速率不均勻,並且請求輸出的速率也不均勻,對後續處理的併發要求比較高。好比:設定服務週期爲1秒,請求的上限閾值爲1000。若是前1ms內已經收到1000個請求,那麼剩下的時間都只能拒絕,並且後端服務須要併發處理1000個請求。

  • 漏桶算法

    ​ 漏桶算法的原理能夠這樣理解,將服務請求想象成流入漏桶的水,漏桶中的水以恆定的速率從桶底流出,當流入漏桶的水速度過快,超過了漏桶容量時,則直接溢出。因此,漏桶算法可以控制服務請求按照固定速率均勻輸出,平滑突發流量,實現流量整形,爲後續處理提供一個穩定的流量。可是,漏桶算法沒法控制請求按照必定的速率均勻輸入。

  • 令牌桶算法

    ​ 令牌桶算法是速率限制(Rate Limiting)和流量整形(Traffic Shaping)中最常使用的一種算法。典型狀況下,令牌桶算法用來控制發送到網絡上的數據的數目,並容許突發數據的發送。

    ​ 首先設定一個能夠存放固定數量的令牌桶,使用某種機制以恆定的速度產生令牌。每次請求調用時,都必須去桶中獲取令牌,只有拿到令牌,才能放行,不然只能等待可用的令牌,或者直接拒絕。若是桶中的令牌消耗的速度小於產生的速度,令牌就會不斷地增多,直至填滿,再產生的令牌就會從桶中溢出。

    ​ 因此,令牌桶算法既能夠控制請求均勻輸入的速度,又能夠控制請求的均勻輸出速率。

3、服務熔斷

​ 咱們在各類場景下都會接觸到熔斷這兩個字。高壓電路中,若是某處電壓太高,熔斷器就會熔斷,對電路進行保護。股票交易中,若是股票漲跌幅過大,也會採用熔斷機制,暫停交易,來控制交易風險。

​ 一樣,在微服務架構中,熔斷機制也是起着相似的做用。當調用鏈路中的某個微服務長時間不可用或者有延遲,響應過慢,系統就會熔斷對該節點微服務的調用,快速返回錯誤信息。當監控到該微服務正常工做後,再次恢復該調用鏈路。

4、Hystrix

​ 服務熔斷和服務限流做爲微服務架構中做爲服務治理的重要手段,在不少開源框架或者產品中都包含了此類功能。好比阿里dubbo,Netflix Hystrix,go-micro,go-kit等。

​ Hystrix是Netflix公司的開源項目,它是一個延遲和故障容錯庫,旨在隔離對遠程系統、服務和第三方庫的訪問點,防止級聯故障,並在沒法避免發生故障的複雜分佈式系統中實現了彈性。

​ Hystrix項目使用了java語言開發,代碼託管地址爲:https://github.com/Netflix/Hystrix。另外,有人使用go語言將該項目進行了移植,代碼託管地址爲:https://github.com/afex/hystrix-go/hystrix。

​ Hystrix能夠作到如下事情:

  • 經過控制延遲和故障來保障第三方服務調用的可靠性
  • 在複雜的分佈式系統中防止級聯故障,防止雪崩
  • 快速失敗、快速恢復
  • 回退並優雅降級
  • 提供近實時監控、報警和操做控制

​ Hystrix 能使你的系統在出現依賴服務失效的時候,經過隔離系統所依賴的服務,防止服務級聯失敗,同時提供失敗回退機制,更優雅地應對失效,並使你的系統能更快地從異常中恢復。

使用Hystrix 很是簡單:

package main

import (
	"github.com/afex/hystrix-go/hystrix"
	"log"
)

func main() {
	// 每一類微服務、遠程系統、第三方庫的調用都被包裝爲一個命令,
	// 調用以前須要先行設置相關的配置信息
	hystrix.ConfigureCommand(
		"ServiceA", // 命令名稱
		hystrix.CommandConfig{
			Timeout:                1000, // 超時時間設置(毫秒)
			MaxConcurrentRequests:  1,    // 最大併發請求數
			ErrorPercentThreshold:  50,   // 錯誤率閾值,超過閾值將熔斷服務
			SleepWindow:            5000, // 服務熔斷後,過多長時間,熔斷器再次檢測是否開啓(毫秒)
			RequestVolumeThreshold: 20,   // 服務熔斷前,所需的最小請求量,請求閾值  熔斷器是否打開首先要知足這個條件;這裏的設置表示至少有5個請求才進行ErrorPercentThreshold錯誤百分比計算
		})

	// 使用hystrix調用遠程服務,並根據命令名稱啓用ConfigureCommand中設置的參數
	_ = hystrix.Do(
		"ServiceA", // 命令名稱
		// 運行函數
		func() error {
			// 調用遠程服務
			log.Println("invoke a remote service")
			return nil
		},
		// 失敗回退函數
		func(err error) error {
			log.Println("fall back")
			return err
		},
	)
}

注:
本文所有源代碼位於:https://github.com/wangshizebin/micro-service
本文時候用的開發工具爲:goland 來自 嗖嗖下載

相關文章
相關標籤/搜索