SpringCloudAlibaba 微服務講解(四)Sentinel--服務容錯(一)

ityml發表於2022-03-29

4.1 高併發帶來的問題

在微服務中,我們將業務拆分成一個個的服務,服務與服務之間可以相互呼叫,但是由於網路原因或者自身的原因,服務並不能保證100%可用,如果單個服務出現問題,呼叫這個服務就會出現網路延遲,此時若有大量的網路湧入,會形成任務堆積,最終導致服務癱瘓。

接下來我們模擬一個高併發的場景

  1. 編寫java程式碼

    @RestController
    @Slf4j
    public calss OrderController2{
    	@Autowired
    	private OrderService orderSerivce;
    	
    	@Autowired
    	private ProductService productService;
    	
    	@RequestMapping("/order/prod/{pid}")
    	public Order order(@Pathvariable("pid") Integer pid){
    		Product product = productService.findByPid(pid);
    		Try{
    		Thread.sleep(100)
    		}catch(InterruptedException e){
    		e.printStackTrace();
    		}
    		Order order = new Order();
    		order.setUid(1);
    		order.setUsername("測試賬號");
    		order.setPid(pid);
    		order.setPname(product.getPname());
    		order.setPprice(product.getPprice());
    		order.setNumber(1);
    		
    		return order;
    		
    	}
    	
    	@RequestMapping("/order/message")
    	public String message(){
    	return "高併發下的問題測試";
    	}
    
    }
    
  2. 配置tocmat 併發數

    server:
    	port:8091
    	tomcat:
    		max-threads: 10 
    
  3. 接下來使用壓測工具,對請求進行壓測

    下載地址:https://jmeter.apache.org

    第一步:修改配置,並啟動軟體

    進入bin目錄,修改jmeter.properties 檔案中的語言支援為language=zh_CN,然後縣級jmeter.bat 啟動軟體。

    第二步:新增執行緒組

    第三步:配置執行緒併發數

    第四步:新增http取樣

    第五步:配置取樣,並啟動測試

  4. 訪問message方法觀察效果

  5. 結論:

    *此時會發現,由於order方法囤積了大量的請求,導致message方法的訪問出現了問題,這就是服務雪崩的雛形

4.2 服務雪崩效應

*在分散式系統中,由於網路原因或者自身原因,服務一版無法保證100%可用,如果一個服務出現了問題,呼叫這個服務就會出現執行緒阻塞的情況,此時若有大量的請求湧入,就會出現多條執行緒阻塞等待,進而導致服務癱瘓

由於服務與服務之間的依賴性,故障會傳播,會對整個微服務系統造成才災難性的嚴重後果,這就是服務故障“雪崩效應”。

雪崩發生的原因多種多樣,有不合理的容量設計,或者是高併發下某一個方法相應變慢,亦或者是某臺機器的資源耗盡。我們無法完全杜絕雪崩源頭的放生,只有做好了足夠的融租哦,保證在一個服務發生問題,不會影響到其他服務的正常執行,也就是“雪落而不雪崩”。

4.3常見的容錯方案

要防止雪崩的擴散,我們就要做好服務的容錯,容錯說白了就是保護自己不被豬隊友拖垮的一些措施,下面介紹常見的服務容錯思路和元件。

常見的容錯思路:

常見的容錯思路有隔離、超時、限流、熔斷、降級這幾種,下面分別介紹下。

  • 隔離

    它是指將系統按照一定的原則劃分為若干個服務模組,各個模組之間相互獨立,無強依賴。當有故障發生時,能將問題和影響隔離在某個模組內部,而不擴散風險,不波及其他模組,不影響整體的系統服務,常見的隔離方式有:執行緒池隔離和訊號量隔離

  • 超時

    在上游服務呼叫下有服務的時候,設定一個最大響應時間,如果炒股哦這個時間,下游未做出反應,就斷開請求,釋放掉執行緒

  • 限流

    限流就是限制系統的輸入和輸出流量已達到保護系統的目的。為了保證系統的穩固執行,一單達到限制的閾值,就需要限制流量並採取少量措施以完成限制流量的目的。

  • 熔斷

    在網際網路系統中,當下有服務因訪問壓力過大而影響變慢或失敗,上游服務為了保護系統整體可用性,可用暫時切斷對下有服務的呼叫,這種犧牲區域性,保全整體的措施就叫做熔斷

    服務熔斷一般有三種狀態:

    • 熔斷關閉狀態(Closed)

      服務沒有故障時,熔斷器所處的狀態,對呼叫方的呼叫不做任何限制

    • 熔斷開啟狀態(Open)

      後續對該服務介面的呼叫不在經過網路,直接執行本地的fallback方法

    • 版熔斷狀態(Half-Open)

      嘗試恢復服務呼叫,允許有限的流量呼叫該服務,並監控呼叫成功率,如果成功率達到預期,則說經服務已恢復,進入熔斷關閉狀態,如果成功率仍舊很低,則重新進入熔斷關閉狀態。

  • 降級

    降級其實就是為服務提供一個託底方案,一單服務無法正常呼叫,就使用託底方案。

4.4常見的容錯元件

  • Hystrix

    Hystrix是由Netflix開源的一個延遲和容錯庫,用於隔離訪問遠端系統、服務或者第三方庫,防止級聯失敗,從而提升系統的可用性和容錯性。

  • Resilience4J

    Resilience4J一款非常輕量、簡單、並且文件非常清晰、豐富的熔斷工具,這也是Hystrix官方推薦的替代產品。不僅如此,Resilience4J還原生支援Spring Boot 1.x/2.x,而且監控也支援和prometheus等多款主流產品進行整合。

  • Sentinel

    Sentinel是阿里巴巴開源的一款斷路器實現,本身在阿里內部已經被大規模採用,非常穩定。

下面是三個元件的在各方面的對比:

4.5Sentinel入門

4.5.1 什麼是Sentinel

Sentinel(分散式系統的流量方衛兵)是阿里巴巴開源的一套用於服務容錯的中和解決方案。它以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度來保護服務的穩定性。

Sentinel具有以下特徵:

  • 豐富的應用場景:Sentinel承接了阿里巴巴近10年的雙十一大促流浪的核心場景,例如秒殺(即突發榴蓮個控制在系統容量可以承受的範圍)、訊息削峰填谷、叢集流量控制、實施熔斷下游不可用應用等。
  • 完備的實時監控:Sentinel提供了實時的監控功能。通過控制檯可以看到接入應用的單臺機器秒級資料,甚至500臺以下規模的叢集的彙總執行情況。
  • 廣泛的開源生態:Sentinel提供了開箱即用的與其他開源框架/庫的整合模組,例如與SpringCloud、Dubbo、gRPC的整合。只需要引入相應的依賴並進行簡單的配置即可快速地接入Sentinel。
  • 完善的SPI擴充套件點:Ssentinel提供了簡單易用、完善的SPI擴充套件介面。您可以通過實現擴充套件介面來快速的定製邏輯。例如定製規則管理、適配動態資料來源等。

Sentinel分為兩個部分

  • 核心庫(Java客戶端)不依賴任何框架、庫,能夠執行於所有java執行時環境,同事對Dubbo/SpringCloud 等框架也有較好的支援。
  • 控制檯(Dashboard)基於Spring Boot開發,打包後可以直接執行,不需要額外的tomcat等應用容器。

4.5.2 微服務整合Sentinel

為微服務整合Sentinel非常的簡單,只需要新增Sentinel的依賴即可

  1. 在pom.xml中新增下面依賴

    <dependency>
    	<groupId>com.alibaba.cloud</groupId>
    	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
  2. 編寫一個Controller測試使用

    @RestController
    @Slf4j
    public class orderCOntroller3{
    	@RequestMapping("/order/message1")
    	public String message2(){
    		return "message1";
    	}
    	
    	@RequestMapping("/order/message2")
    	public String message2(){
    		return "message2";
    	}
    }
    

4.5.3 安裝Sentinel控制檯

Sentinel提供一個輕量級的控制檯,它提供機器發現、單機資源實時監控以及規則管理等功能。

  1. 下載jar包,解壓到資料夾。https://github.com/alibaba.Sentinel/releases

  2. 啟動控制檯

    java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-xxx.jar
    
  3. 修改shop-order,在裡面加入有關控制檯的配置

    spring:
    	cloud:
    		sentinel:
    			transport:
    				port: 9999
    				dashboard: localhost:8080 		
    
  4. 通過瀏覽器訪問localhost:8080 進入控制檯(預設使用者名稱密碼是:sentinel/sentinel)

  5. 補充:

    Sentinel的控制檯其實就是一個Soringboot編寫的程式。我們需要將我們的微服務程式註冊到控制檯上,即在微服務中指定控制檯的地址,並且還要開一個跟控臺傳遞資料的埠,控制檯也可以通過次埠呼叫微服務中的監控程式獲取微服務的各種資訊。

4.5.4 實現一個介面的限流

  1. 通過控制檯為message1新增一個流控規則

  1. 通過控制檯快速頻繁訪問,觀察效果

4.6 Sentinel的概念和功能

4.6.1 基本概念

  • 資源

    資源就是Sentinel要保護的東西,資源是Sentinel的關鍵概念。它可以是java應用程式中的任何內容,可以是一個服務,也可以是一個方法,甚至是一段程式碼。

    我們入門案例中的message1方法就可以認為是一個資源

  • 規則

    規則就是用來定義如何進行保護資源的,作用在資源之上,定義以什麼樣的方式保護資源,主要包括裡流量控制規則,熔斷降級規則以及系統保護規則。

    我們入門案例中就是message1資源設定了一種流控規則,限制了進入message1的流量。

4.6.2 重要功能

Sentinel的主要功能就是容錯,主要體現為一下3個方面:

  • 流量控制

    流量控制在網路傳輸中是有一個常用的概念, 它用於調整網路包的資料,任意時間來到請求往往是隨機不可控的,而系統的處理能力是有限的的,我們需要根據系統的處理能力對流量進行控制,Sentinel作為一個調配器,可以根據需要把隨機的請求調整為合適的形狀。

  • 熔斷降級

    當檢測到呼叫鏈路中某個資源出現不穩定的表現,例如請求響應時間長或者比例升高的時候,則對這個資源的呼叫進行限制,讓請求快速失敗,避免影響到其他的資源而導致級聯故障

Sentinel對這個問題採取了兩種手段

  • 通過併發執行緒數進行控制

    Sentinel通過限制資源併發執行緒的數量,來減少不穩定資源對其他資源的影響,當某個資源出現不穩定的情況下,例如響應時間過長,對資源的直接影響就是會造成執行緒數的逐步堆積。當執行緒數在特定資源上堆積到一定的數量之後,對該資源的新請求就會被拒絕。堆積的執行緒完成任務後才開始繼續接受請求。

  • 通過響應誰極愛你對資源進行降級

    除了對併發執行緒進行控制以外,Sentinel還可以通過響應時間來快速降級不穩定的資源,當依賴對資源出現響應時間過長後,所有對改資源的訪問都會被直接拒絕,知道過了指定的時間視窗之後才重新恢復。

Sentinel 和 Hystrix 的區別

兩者的原則是一直的,都是當一個資源出現問題時,讓其快速失敗,不要波及到其他服務,但是限制的手段上,卻採用了完全不一樣的方法

  • Hystrix 採用的是執行緒池隔離的方法,優點是做到了資源之間的隔離,缺點是增加了執行緒切換的成本
  • Sentinel採用的是通過併發執行緒的數量和響應時間來對資源做限制
  • 系統負載保護

    Sentinel同事提供了系統維度的自適應保護能力,當系統負載較高的時候,如果還持續讓請求進入可能會導致系統奔潰,無法響應。在叢集環境下,會把本應該這臺機器承載的流量轉發到其他的機器上去,如果這個時候其他的機器出在一個邊緣狀態的時候,Sentinel提供了對應的保護機制,讓系統的入口流量和系統的負載達到一個平衡,保證系統在能力範圍之內處理最多的請求

總之一句話:我們需要做的事情,就是在Sentinel的資源上配置各種各樣的規則,來實現各種容錯的功能。

相關文章