动态

详情 返回 返回

【Spring開發】SpringCloud服務端高級框架第1篇:微服務保護,1.初識Sentinel【附代碼文檔】 - 动态 详情

🏆🏆🏆教程全知識點簡介:微服務保護、服務異步通信、消息中間件部署、分佈式事務、搜索引擎、緩存、數據同步以及相關組件的安裝配置等技術要點。在微服務保護方面,介紹了 Sentinel 的基礎知識,包括雪崩問題、超時處理、艙壁模式、斷路器機制,以及不同服務保護技術的對比;講解了流量控制(簇點鏈路、流控模式、熱點參數限流)、隔離與降級(FeignClient 整合 Sentinel、線程隔離)、授權規則(自定義異常結果)及規則持久化(規則管理模式與 pull 模式),並演示了基於 Nacos 的規則持久化改造。服務異步通信部分探討了消息可靠性(生產者消息確認、Return 回調、ConfirmCallback)、死信交換機、TTL 隊列等高級應用。RabbitMQ 部署指南涵蓋了單機部署、DelayExchange 插件安裝、集羣部署、鏡像模式等內容。分佈式事務部分介紹了 CAP 定理、BASE 理論、常見解決方案,Seata 的基礎與部署(TC 服務部署、Nacos 配置、數據庫表創建)、多種事務模式(XA 模式及優缺點、四種模式對比)和高可用架構。分佈式搜索引擎章節講解了 Elasticsearch 的原理(ELK 技術棧、倒排索引)、索引庫與文檔操作、RestAPI 與 RestClient 的使用、排序與高亮、酒店搜索案例(分頁、競價排名、廣告標記、算分函數)、自動補全、數據同步(同步調用、監聽 binlog)、集羣搭建與腦裂問題、分片存儲測試,以及單點 ES、Kibana、IK 分詞器安裝。緩存部分介紹了 Redis 持久化(RDB 與 AOF 對比)、單機安裝 Redis、Redis 集羣、多級緩存(JVM 進程緩存、Caffeine)、請求參數處理、Tomcat 查詢、HTTP 工具與 CJSON 工具類、Redis 緩存查詢。數據同步與網關部分包括 Canal 安裝(開啓 MySQL 主從、設置權限)、OpenResty 安裝(開發庫、目錄結構、環境變量配置)及運行流程。

<!-- start:bj1 -->

📚📚👉👉👉   https://gitee.com/xiaoshuai112/Backend/blob/master/Spring/Spr... 🍅🍅

<!-- end:bj1 -->

✨ 本教程項目亮點

🧠 知識體系完整:覆蓋從基礎原理、核心方法到高階應用的全流程內容
💻 全技術鏈覆蓋:完整前後端技術棧,涵蓋開發必備技能
🚀 從零到實戰:適合 0 基礎入門到提升,循序漸進掌握核心能力
📚 豐富文檔與代碼示例:涵蓋多種場景,可運行、可複用
🛠 工作與學習雙參考:不僅適合系統化學習,更可作為日常開發中的查閲手冊
🧩 模塊化知識結構:按知識點分章節,便於快速定位和複習
📈 長期可用的技術積累:不止一次學習,而是能伴隨工作與項目長期參考

🎯🎯🎯全教程總章節


🚀🚀🚀本篇主要內容

微服務保護

1.初識Sentinel

1.1.雪崩問題及解決方案

1.1.1.雪崩問題

微服務中,服務間調用關係錯綜複雜,一個微服務往往依賴於多個其它微服務。

如圖,如果服務提供者I發生了故障,當前的應用的部分業務因為依賴於服務I,因此也會被阻塞。此時,其它不依賴於服務I的業務似乎不受影響。

但是,依賴服務I的業務請求被阻塞,用户不會得到響應,則tomcat的這個線程不會釋放,於是越來越多的用户請求到來,越來越多的線程會阻塞:

服務器支持的線程和併發數有限,請求一直阻塞,會導致服務器資源耗盡,從而導致所有其它服務都不可用,那麼當前服務也就不可用了。

那麼,依賴於當前服務的其它服務隨着時間的推移,最終也都會變的不可用,形成級聯失敗,雪崩就發生了:

1.1.2.超時處理

解決雪崩問題的常見方式有四種:

•超時處理:設定超時時間,請求超過一定時間沒有響應就返回錯誤信息,不會無休止等待

1.1.3.倉壁模式

方案2:倉壁模式

倉壁模式來源於船艙的設計:

船艙都會被隔板分離為多個獨立空間,當船體破損時,只會導致部分空間進入,將故障控制在一定範圍內,避免整個船體都被淹沒。

於此類似,我們可以限定每個業務能使用的線程數,避免耗盡整個tomcat的資源,因此也叫線程隔離。

1.1.4.斷路器

斷路器模式:由斷路器統計業務執行的異常比例,如果超出閾值則會熔斷該業務,攔截訪問該業務的一切請求。

斷路器會統計訪問某個服務的請求數量,異常比例:

當發現訪問服務D的請求異常比例過高時,認為服務D有導致雪崩的風險,會攔截訪問服務D的一切請求,形成熔斷:

1.1.5.限流

流量控制:限制業務訪問的QPS,避免服務因流量的突增而故障。

1.1.6.總結

什麼是雪崩問題?

  • 微服務之間相互調用,因為調用鏈中的一個服務故障,引起整個鏈路都無法訪問的情況。

MyBatis-Spring 集成

可以認為:

限流是對服務的保護,避免因瞬間高併發流量而導致服務故障,進而避免雪崩。是一種預防措施。

超時處理、線程隔離、降級熔斷是在部分服務故障時,將故障控制在一定範圍,避免雪崩。是一種補救措施。

1.2.服務保護技術對比

在SpringCloud當中支持多種服務保護技術:

早期比較流行的是Hystrix框架,但目前國內實用最廣泛的還是阿里巴巴的Sentinel框架,這裏我們做下對比:

Sentinel Hystrix
隔離策略 信號量隔離 線程池隔離/信號量隔離
熔斷降級策略 基於慢調用比例或異常比例 基於失敗比率
實時指標實現 滑動窗口 滑動窗口(基於 RxJava)
規則配置 支持多種數據源 支持多種數據源
擴展性 多個擴展點 插件的形式
基於註解的支持 支持 支持
限流 基於 QPS,支持基於調用關係的限流 有限的支持
流量整形 支持慢啓動、勻速排隊模式 不支持
系統自適應保護 支持 不支持
控制枱 開箱即用,可配置規則、查看秒級監控、機器發現等 不完善
常見框架的適配 Servlet、Spring Cloud、Dubbo、gRPC 等 Servlet、Spring Cloud Netflix

1.3.Sentinel介紹和安裝

2.流量控制

雪崩問題雖然有四種方案,但是限流是避免服務因突發的流量而發生故障,是對微服務雪崩問題的預防。我們先學習這種模式。

2.1.簇點鏈路

當請求進入微服務時,首先會訪問DispatcherServlet,然後進入Controller、Service、Mapper,這樣的一個調用鏈就叫做簇點鏈路。簇點鏈路中被監控的每一個接口就是一個資源

默認情況下sentinel會監控SpringMVC的每一個端點(Endpoint,也就是controller中的方法),因此SpringMVC的每一個端點(Endpoint)就是調用鏈路中的一個資源。

例如,我們剛才訪問的order-service中的OrderController中的端點:/order/{orderId}

流控、熔斷等都是針對簇點鏈路中的資源來設置的,因此我們可以點擊對應資源後面的按鈕來設置規則:

  • 流控:流量控制
  • 降級:降級熔斷
  • 熱點:熱點參數限流,是限流的一種
  • 授權:請求的權限控制

2.1.快速入門

2.1.1.示例

點擊資源/order/{orderId}後面的流控按鈕,就可以彈出表單。

表單中可以填寫限流規則,如下:

其含義是限制 /order/{orderId}這個資源的單機QPS為1,即每秒只允許1次請求,超出的請求會被攔截並報錯。

2.1.2.練習:

需求:給 /order/{orderId}這個資源設置流控規則,QPS不能超過 5,然後測試。

1)首先在sentinel控制枱添加限流規則

2)利用jmeter測試

如果沒有用過jmeter,可以參考課前資料提供的文檔《Jmeter快速入門.md》

課前資料提供了編寫好的Jmeter測試樣例:

打開jmeter,導入課前資料提供的測試樣例:

選擇:

20個用户,2秒內運行完,QPS是10,超過了5.

選中流控入門,QPS<5右鍵運行:

注意,不要點擊菜單中的執行按鈕來運行。

結果:

可以看到,成功的請求每次只有5個

2.2.流控模式

在添加限流規則時,點擊高級選項,可以選擇三種流控模式

Spring Data Redis 文檔

  • 直接:統計當前資源的請求,觸發閾值時對當前資源直接限流,也是默認的模式
  • 關聯:統計與當前資源相關的另一個資源,觸發閾值時,對當前資源限流
  • 鏈路:統計從指定鏈路訪問到本資源的請求,觸發閾值時,對指定鏈路限流

快速入門測試的就是直接模式。

2.2.1.關聯模式

關聯模式:統計與當前資源相關的另一個資源,觸發閾值時,對當前資源限流

配置規則

語法説明:當/write資源訪問量觸發閾值時,就會對/read資源限流,避免影響/write資源。

使用場景:比如用户支付時需要修改訂單狀態,同時用户要查詢訂單。查詢和修改操作會爭搶數據庫鎖,產生競爭。業務需求是優先支付和更新訂單的業務,因此當修改訂單業務觸發閾值時,需要對查詢訂單業務限流。

需求説明

  • 在OrderController新建兩個端點:/order/query和/order/update,無需實現業務
  • 配置流控規則,當/order/ update資源被訪問的QPS超過5時,對/order/query請求限流

1)定義/order/query端點,模擬訂單查詢

@GetMapping("/query")
public String queryOrder() {
    return "查詢訂單成功";
}

2)定義/order/update端點,模擬訂單更新

@GetMapping("/update")
public String updateOrder() {
    return "更新訂單成功";
}

重啓服務,查看sentinel控制枱的簇點鏈路:

3)配置流控規則

對哪個端點限流,就點擊哪個端點後面的按鈕。我們是對訂單查詢/order/query限流,因此點擊它後面的按鈕:

Lettuce Redis 客户端

在表單中填寫流控規則:

4)在Jmeter測試

選擇《流控模式-關聯》:

W3Schools Java

可以看到1000個用户,100秒,因此QPS為10,超過了我們設定的閾值:5

查看http請求:

請求的目標是/order/update,這樣這個斷點就會觸發閾值。

Google Guava 文檔

但限流的目標是/order/query,我們在瀏覽器訪問,可以發現:

確實被限流了。

5)總結

2.2.2.鏈路模式

鏈路模式:只針對從指定鏈路訪問到本資源的請求做統計,判斷是否超過閾值。

配置示例

例如有兩條請求鏈路:

  • /test1 --> /common
  • /test2 --> /common

如果只希望統計從/test2進入到/common的請求,則可以這樣配置:

實戰案例

需求:有查詢訂單和創建訂單業務,兩者都需要查詢商品。針對從查詢訂單進入到查詢商品的請求統計,並設置限流。

步驟:

  1. 在OrderService中添加一個queryGoods方法,不用實現業務
  2. 在OrderController中,改造/order/query端點,調用OrderService中的queryGoods方法
  3. 在OrderController中添加一個/order/save的端點,調用OrderService的queryGoods方法
  4. 給queryGoods設置限流規則,從/order/query進入queryGoods的方法限制QPS必須小於2

實現:

1)添加查詢商品方法

在order-service服務中,給OrderService類添加一個queryGoods方法:

public void queryGoods(){
    System.err.println("查詢商品");
}
2)查詢訂單時,查詢商品

在order-service的OrderController中,修改/order/query端點的業務邏輯:

@GetMapping("/query")
public String queryOrder() {
    // 查詢商品
    orderService.queryGoods();
    // 查詢訂單
    System.out.println("查詢訂單");
    return "查詢訂單成功";
}
3)新增訂單,查詢商品

在order-service的OrderController中,修改/order/save端點,模擬新增訂單:

@GetMapping("/save")
public String saveOrder() {
    // 查詢商品
    orderService.queryGoods();
    // 查詢訂單
    System.err.println("新增訂單");
    return "新增訂單成功";
}

JProfiler 文檔

Java 語言規範

4)給查詢商品添加資源標記

默認情況下,OrderService中的方法是不被Sentinel監控的,需要我們自己通過註解來標記要監控的方法。

給OrderService的qu

Add a new 评论

Some HTML is okay.