🏆🏆🏆教程全知識點簡介:微服務保護、服務異步通信、消息中間件部署、分佈式事務、搜索引擎、緩存、數據同步以及相關組件的安裝配置等技術要點。在微服務保護方面,介紹了 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.總結
什麼是雪崩問題?
- 微服務之間相互調用,因為調用鏈中的一個服務故障,引起整個鏈路都無法訪問的情況。
可以認為:
限流是對服務的保護,避免因瞬間高併發流量而導致服務故障,進而避免雪崩。是一種預防措施。
超時處理、線程隔離、降級熔斷是在部分服務故障時,將故障控制在一定範圍,避免雪崩。是一種補救措施。
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.流控模式
在添加限流規則時,點擊高級選項,可以選擇三種流控模式:
- 直接:統計當前資源的請求,觸發閾值時對當前資源直接限流,也是默認的模式
- 關聯:統計與當前資源相關的另一個資源,觸發閾值時,對當前資源限流
- 鏈路:統計從指定鏈路訪問到本資源的請求,觸發閾值時,對指定鏈路限流
快速入門測試的就是直接模式。
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限流,因此點擊它後面的按鈕:
在表單中填寫流控規則:
4)在Jmeter測試
選擇《流控模式-關聯》:
可以看到1000個用户,100秒,因此QPS為10,超過了我們設定的閾值:5
查看http請求:
請求的目標是/order/update,這樣這個斷點就會觸發閾值。
但限流的目標是/order/query,我們在瀏覽器訪問,可以發現:
確實被限流了。
5)總結
2.2.2.鏈路模式
鏈路模式:只針對從指定鏈路訪問到本資源的請求做統計,判斷是否超過閾值。
配置示例:
例如有兩條請求鏈路:
- /test1 --> /common
- /test2 --> /common
如果只希望統計從/test2進入到/common的請求,則可以這樣配置:
實戰案例
需求:有查詢訂單和創建訂單業務,兩者都需要查詢商品。針對從查詢訂單進入到查詢商品的請求統計,並設置限流。
步驟:
- 在OrderService中添加一個queryGoods方法,不用實現業務
- 在OrderController中,改造/order/query端點,調用OrderService中的queryGoods方法
- 在OrderController中添加一個/order/save的端點,調用OrderService的queryGoods方法
- 給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 "新增訂單成功";
}
4)給查詢商品添加資源標記
默認情況下,OrderService中的方法是不被Sentinel監控的,需要我們自己通過註解來標記要監控的方法。
給OrderService的qu