SpringCloud【Sentinel】

1,工作原理

2,常見規則

流量控制(FlowRule)

1,閾值類型設置如下

單機均攤:每個機器均攤,比如閾值填5,三個機器,就個機器都可以有5個

總體閾值:所有機器總閾值,比如閾值填5,三個機器,總共進5個請求

2,流控模式設置如下

只有流控效果是快速失敗才支持調整流控模式?

直接:默認,限制請求直接對資源進行限制

關聯:數據庫讀寫,當寫比較大時,限制讀的限流,達到優先寫

關聯測試案例

先添加倆方法,一個讀一個寫,在orderControoler類中

  @GetMapping("/readDb")public String readDb(){return "readDb.....";}@GetMapping("/writeDb")public String writeDb(){return "writeDb.....";}

然后調用倆接口,在dashborard中查看倆資源,進行如下設置,即在讀的資源下設置限流,流控模式為關聯,關聯資源為writeDb,則可實現寫量過大時,訪問讀會被限流(設置好之后,測試先訪問readDb,正常訪問也沒被限流,但再訪問writeDb的時候,瘋狂刷新,再回去訪問readDb則readDb就會被限流)

鏈路: 根據不同的調用鏈,來控制不同調用鏈

鏈路測試案例

添加一個seckill方法,同createOrder,在orderController類中

   @GetMapping("/create")public Order createOrder(@RequestParam("userId") Long userId, @RequestParam("productId") Long productId){Order order = orderService.createOrder(userId,productId);return order;}@GetMapping("/seckill")public Order seckill(@RequestParam("userId") Long userId, @RequestParam("productId") Long productId){Order order = orderService.createOrder(userId,productId);order.setId(999l);return order;}

yml配置文件添加配置,取消統一上下文

spring:cloud:sentinel:web-context-unify: false      #是否統一web上下文(默認true)

配置鏈路規則:需要對createOrder限流,則如下設置,設置完之后測試,分別測試create接口和seckill接口,則會發現create接口隨便刷新無誤,seckill接口就有了一秒一個的限制

3,流控效果設置如下

快速失敗:(默認)如果沒有超閾值,就交給業務處理,如果超過了,多余的請求就會拋出blockHandler異常(比如每秒一個,哪么這一秒其他多的請求會被直接丟棄)

Warm Up:leng'q如果預見超高峰流量即將到達,設置參數參數QPS(每秒通過幾個請求),period(冷啟動周期),流程比如QPS=10,period=3,請求是一個穩步上升的趨勢,而不是突然增加(每秒多余的請求會被丟棄)

排隊等待:勻速排隊,比如QPS=2,則每秒會通過2個請求,但其他請求不會被丟棄,而是在后面排隊,等前面的請求,排隊也有最大等待時間,timeout=100,超過最大等待時間也會被丟棄,如下每秒2個請求

熔斷降級(DegradeRule)

思想:如下圖的復雜調用關系,A->G->D,B->F->D,如果此時D不穩定,一直不返回結果,那么如果G一直去等D的結果,D也會卡住,同樣A也會卡住,此時我們就需要及時切斷這種不穩定的調用,當G感知到D調用很慢之后,后面就采取措施不調用或者快速返回,切斷跟D的聯系,快速返回錯誤,整個鏈路才會快速結束,請求不積壓,則不會產生服務雪崩問題

此中間就有一個斷路器的概念,當調用的B是穩定通暢的,則斷路器是關閉的,一旦B出現了問題,則A就會打開,怎么知道什么時候該打開呢,此時就會有一個半開狀態,就是稍微開一下,測一下當前狀態如果調用不慢了,則閉合,如果調用仍然慢,則打開

斷路器工作原理如下:

首先默認斷路器是關閉的,調用是通的,此時我們設置慢調用比例(熔斷策略:滿調用比例/異常比例/異常數),比如設置0.7,就是請求70%都是慢請求(慢調用設置時長閾值)的話,就打開斷路器,調用就會失敗,但也不能一直打開,此時就會有一個熔斷時長,比如30s,這30s以內的所有請求不調用,直接返回失敗,但30s之后熔斷窗口就結束,結束后斷路器就會變成半開狀態,A需要調用B就會放一個請求過去探測一下,調用成功,則B又可靠了,斷路器閉合,如果還是調用失敗或者慢,則斷路器還是打開

熔斷策略測試案例

慢調用比例

首先運行Order和Product服務,然后給CreateOrder設置熔斷規則如下

修改一下商品服務,加個睡眠時長2秒,達到慢請求要求

在productController中的方法里加入睡眠時長

 @GetMapping("/getProductById/{productId}")public Product getProductById(@PathVariable("productId") Long productId, HttpServletRequest request) {String header = request.getHeader("X-Token");System.out.println("product==="+header);try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}Product product = productService.getProductById(productId);return product;}
}

然后測試,調用createOrder接口, 先5秒內刷新超過5個請求吧,開始的請求會比較慢,5秒后就會很快,應為斷路器打開了,就不再調用了,后臺也不再打印,order服務就會返回兜底回調,30秒之后,在測試刷新接口,會有一個慢請求之后,又會變快,因為半開測試之后,斷路器仍舊打開了,選擇不調用。去掉getProductById里面的睡眠,在重啟商品服務,熔斷規則還在,然后再測試接口調用,則正常調用,因為不存在慢調用問題

異常比例

同上構造異常調用

修改一下商品服務,加一個異常

在productController中的方法里加入異常代碼

 @GetMapping("/getProductById/{productId}")public Product getProductById(@PathVariable("productId") Long productId, HttpServletRequest request) {String header = request.getHeader("X-Token");System.out.println("product==="+header);
//        try {
//            Thread.sleep(2000);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }int a=10/0;Product product = productService.getProductById(productId);return product;}

然后同上測試方法進行測試看效果

當沒有加熔斷的時候通過后天打印可以看出,每次A調用B 之后,都會返回異常,但是每次還是會調用,加了熔斷規則之后,達到規則之后,30s內就不會再調用,就直接執行兜底回調,不用再走一遍失敗的路

異常數

測試也同上面一樣

系統保護(SystemRule)

來源訪問控制(AuthorityRule)

熱點參數(ParamFlowRule)

類似流控規則,只是更細話到參數上面的限制

測試案例如下

場景1:每個用戶秒殺QPS不得超過1(秒殺下單userId級別)

我們可以先寫一個資源,在orderController中

   //添加上sentinel資源注解@GetMapping("/seckill")@SentinelResource(value = "seckill-order",blockHandler = "seckillFallback")public Order seckill(@RequestParam(value = "userId",required = false) Long userId, @RequestParam(value = "productId",required = false) Long productId){Order order = orderService.createOrder(userId,productId);order.setId(999l);return order;}public Order seckillFallback(Long userId, Long productId, BlockException e){Order order = new Order();order.setId(-1l);order.setTotalAmount(BigDecimal.ZERO);order.setAddress("異常信息-----");return order;}

啟動訂單服務,設置熱點參數規則?

有參數userId,快速刷新效果,會限制1秒一個

去掉userId,快速刷新效果,不會限制

場景2:6號是vip用戶,需要放行,不限制QPS

場景3:666號商品已經下架,不可訪問

此時需要對另外一個參數進行限流,則需要再加一個限流規則

3,基礎場景

1,下載sentinel-dashboard控制臺

https://github.com/alibaba/Sentinel/releases/tag/1.8.8

Sentinel-Dashboard?是?阿里巴巴?開源的?流量控制組件?Sentinel的?可視化控制臺?,主要用于?微服務架構?的流量治理,支持實時監控、動態配置規則、熔斷降級等功能

下載好之后,在文件夾中cmd,開啟命令模式

然后輸入java -jar sentinel-dashboard-1.8.8.jar啟動

啟動之后,瀏覽器輸入http://localhost:8080/? ?即可訪問,賬密sentinel sentinel

2,添加配置

spring:cloud:sentinel:transport:dashboard: localhost:8080   #dashboard控制臺eager: true                   #提前加載(本來是訪問了請求才會加載,此時項目啟動就會連接加載)

3,啟動服務之后,查看控制臺

4,在OrderServiceImpl得createOrder方法上添加注解@SentinelResource(value = "createOrder")

   @SentinelResource(value = "createOrder")@Overridepublic Order createOrder(Long userId, Long productId) {
//        Product product = getProductByRemoteWithLoadBalancerByAnnotatin(productId);Product product = productFeignClient.getProductById(productId);Order order = new Order();order.setId(1l);//todo  遠程調用order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));order.setUserId(userId);order.setNickName("愛學習");order.setAddress("北京");//todo  遠程調用order.setProductList(Arrays.asList(product));return order;}

5,重新啟動訂單服務,然后調用create接口,查看控制臺?

6,測試規則---流控

7,然后調用createorder接口,一秒一刷則無妨,但一秒超過一次請求就會報錯

4,異常處理

如上會默認返回一個流控錯誤字符串,我們需要返回json數據,返回錯誤消息和數據則就需要異常處理機制,常見得集中異常和處理方式如下:

1,Web接口

-----實現:AbstractSentinelInterceptor

異常處理,我們自己寫個異常處理類,實現BlockExceptionHandler,添加到容器

新增類MyBlockExceptionHandler?

package org.example.order.exception;import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.common.R;
import org.springframework.stereotype.Component;import java.io.PrintWriter;@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {private ObjectMapper objectMapper = new ObjectMapper();@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response,String resourceName, BlockException e) throws Exception {response.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();R error = R.error(500, resourceName + "被Sentinel限制了" + e.getClass());//寫出jsonString s = objectMapper.writeValueAsString(error);writer.write(s);writer.flush();writer.close();}
}

新增一個異常已處理對象R

在公共model模塊添加對象

package org.example.common;import lombok.Data;@Data
public class R {private Integer code;private String msg;private Object data;public static R ok(){R r = new R();r.setCode(200);return r;}public static R ok(Object data, String msg){R r = new R();r.setCode(200);r.setData(data);r.setMsg(msg);return r;}public static R error(){R r = new R();r.setCode(500);return r;}public static R error(Integer code, String msg){R r = new R();r.setCode(code);r.setMsg(msg);return r;}}

然后重新啟動,在dashboard中加入流控規則,調用接口,快速刷新即可看到以下報錯

2,@SentinelResource

------實現:SentinelResourceAspect

@SentinelResource一般標注在非controller層,一旦違反規則,如果業務規定有回調數據,那就用blockHandle去指定兜底回調,如果沒有指定回調,就讓異常拋給全局(springboot全局異常處理器),此注解得處理(SentinelResourceAspect)

回調處理

1,在方法上加上注解

?@SentinelResource(value = "createOrder",blockHandler = "createOrderFallback")

2,添加回調方法

加上回調得方法,方法名通上面得注解里面blockHandler,其他內容需通上方注解方法,public、返回、參數

OrderServiceImpl

    //增加回調createOrderFallback@SentinelResource(value = "createOrder",blockHandler = "createOrderFallback")@Overridepublic Order createOrder(Long userId, Long productId) {
//        Product product = getProductByRemoteWithLoadBalancerByAnnotatin(productId);Product product = productFeignClient.getProductById(productId);Order order = new Order();order.setId(1l);//todo  遠程調用order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));order.setUserId(userId);order.setNickName("愛學習");order.setAddress("北京");//todo  遠程調用order.setProductList(Arrays.asList(product));return order;}//同一個類中,加上回調得方法,方法名通上面得注解里面blockHandler,其他內容需通上方注解方法,public、返回、參數public Order createOrderFallback(Long userId, Long productId, BlockException e) {Order order = new Order();order.setId(0l);order.setTotalAmount(BigDecimal.ZERO);order.setUserId(userId);order.setNickName("未知用戶");order.setAddress("異常信息:"+e.getClass());return order;}

添加流控規則

測試快速刷新的異常處理結果

3,OpenFeign調用

-----實現:SentinelFeignAutoConfiguration

在openFeign筆記中提到過兜底回調,此處即用

首先編寫一個兜底返回org.example.order.feign.fallback.ProductFeignClientFallback?

實現ProductFeignClient 接口

package org.example.order.feign.fallback;
import java.math.BigDecimal;import org.example.order.feign.ProductFeignClient;
import org.example.producet.domain.Product;
import org.springframework.stereotype.Component;@Component
public class ProductFeignClientFallback implements ProductFeignClient {@Overridepublic Product getProductById(Long id) {Product product = new Product();product.setId(id);product.setPrice(new BigDecimal("0"));product.setProducetName("兜底回調的數據");product.setNum(0);return product;}
}

在ProductFeignClient 接口中添加fallback = ProductFeignClientFallback.class,這時,在遠程調用成功則不管,如果調用失敗,則會調用fallback,返回ProductFeignClientFallback里面編寫的默認數據

package org.example.order.feign;import org.example.order.feign.fallback.ProductFeignClientFallback;
import org.example.producet.domain.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;//需要調用的服務的名字
@FeignClient(value = "services-product",fallback = ProductFeignClientFallback.class)
public interface ProductFeignClient {@GetMapping("/getProductById/{id}")Product getProductById(@PathVariable("id") Long id);}

添加流控規則

測試異常回調處理結果

同樣,如果此處沒有些回調函數,就會拋給springboot全局異常處理

4,Sphu硬編碼?

以上三種異常處理的源碼都會有的編碼

SphU.entry(resourceName);

我們也可自定義比如?

try {Entry hahah = SphU.entry("hahah");order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));order.setUserId(userId);order.setNickName("愛學習");order.setAddress("北京");} catch (BlockException e) {throw new RuntimeException(e);}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/92590.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/92590.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/92590.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解構未來金融:深入剖析DeFi與去中心化交易所(DEX)的技術架構

今天,我們來聊一個顛覆傳統金融界的熱門話題——DeFi(去中心化金融)。大家可能聽說過它如何承諾將銀行、交易所、保險等金融服務構建在一個開放、無需許可的區塊鏈網絡上。而這一切魔法的核心,正是其獨特的“技術架構”。 在這篇文…

中國西北典型綠洲區土壤水分特征(2018-2019年)

數據集摘要該數據包含張掖綠洲黑河沿岸濕地、過渡帶楊樹林土壤水分、溫度數據。數據采集時間為2018年至2019年,采集地點為張掖綠洲,數據為日數據。該數據集是按照課題制定的試驗方案和中國生態系統研究網絡編著的陸地生態系統水土氣生觀測規范進行數據的…

MySQL高可用部署

目錄 一、MHA(一主多從模式) 1.環境準備(所有節點) 2. 部署 MySQL 主從復制(MasterSlave) 3.部署 MHA Manager(管理節點) (1)安裝 MHA Manager &#xf…

從 XSS 到 Bot 攻擊:常見網絡攻擊防不勝防?雷池 WAF 用全場景防護為網站筑牢安全墻

1. 網絡攻擊類型當前常見的網絡攻擊類型包括:重放攻擊(HTTP Request Replay Attack):攻擊者截獲合法用戶的 HTTP 請求并重新發送,以欺騙服務器執行相同操作。危害包括消耗服務器資源、大量抓取數據或繞過認證操作敏感接…

【王樹森推薦系統】推薦系統漲指標的方法05:特殊用戶人群

為什么要特殊對待特殊人群? 新用戶,低活用戶的行為很少,個性化推薦不準確。個性化的召回和排序都需要基于用戶的歷史行為,如果歷史行為少,個性化就做不好,尤其是新用戶,這就需要策略把個性化做的…

Java 大視界 -- Java 大數據在智能家居能源管理與節能優化中的深度應用(361)

Java 大視界 -- Java 大數據在智能家居能源管理與節能優化中的深度應用(361)引言:正文:一、Java 構建的智能家居能源數據架構1.1 多源能耗數據實時采集1.2 家庭能源畫像與異常檢測二、Java 驅動的節能策略與智能控制2.1 多場景節能…

從零開始的云計算生活——番外5,使用ELK實現對應用日志的監控

目錄 一.環境準備 試驗機安裝 修改文件配置 二.收集測試機(test)日志 配置pipline文件 配置filebeat配置文件 三.收集測試機nginx日志 下載安裝nginx 修改filebeat文件 修改pipline文件 四.收集網絡服務模塊日志 1.DHCP 下載dhcp 修改配置…

Node.js:函數、路由、全局對象

Node.js函數 在JavaScript中,一個函數可以作為另一個函數的參數,可以先定義一個函數,然后進行傳遞,也可以在傳參的地方直接定義 function sayhello(){console.log("hello"); } function run(hello, value){hello();cons…

2025暑期—06神經網絡-常見網絡3

VGG16網絡64個卷積核做兩次卷積,填充后編程224X224X64 pooling 兩次卷 pooling 三次卷...分辨率降低一半,通道數增加1倍所有卷積核都是3x3, 所有的pooling 都是2x2殘差網絡每一層的塊都有越層的連接。

使用 FastAPI 構建 Elasticsearch API

作者:來自 Elastic Jeffrey Rengifo 學習如何使用 Pydantic 模式和 FastAPI 后臺任務,通過實際示例構建一個 Elasticsearch API。 想獲得 Elastic 認證嗎?查看下一期 Elasticsearch Engineer 培訓的時間! Elasticsearch 擁有豐富…

[2025CVPR-目標檢測方向]FSHNet:一種用于3D物體檢測的全稀疏混合網絡。

1. ?簡介? 論文提出了FSHNet(Fully Sparse Hybrid Network),一種用于3D物體檢測的全稀疏混合網絡。FSHNet旨在解決現有稀疏3D檢測器的兩大核心問題:長距離交互能力弱和網絡優化困難。稀疏檢測器(如VoxelNeXt和SAFDN…

MySql 8.0.42 zip版安裝教程和使用

今天要裝個MySQL,就按照自己以前的教程來做,不知道是不是版本更新了的原因,又遇到了一點小阻礙,于是再記錄一下吧。 下載MySQL 下載鏈接:MySQL :: Download MySQL Community Serverhttps://dev.mysql.com/downloads/…

【lucene】實現knn

在 Lucene 中,可以通過 KnnFloatVectorQuery 和 KnnFloatVectorField 來實現 KNN(k-Nearest Neighbors)搜索。以下是具體介紹:1. 功能原理KnnFloatVectorQuery 是 Lucene 用于執行最近鄰搜索的查詢類,它可以在一個字段…

RabbitMQ實踐學習筆記

RabbitMQ實踐 以下是關于RabbitMQ實踐的整理,涵蓋常見場景和示例代碼(基于Markdown格式)。內容按模塊分類,避免步驟詞匯,直接提供可操作的方法: 基礎連接與隊列聲明 使用Python的pika庫建立連接并聲明隊列: import pikaconnection = pika.BlockingConnection(pika.C…

量子生成對抗網絡:量子計算與生成模型的融合革命

引言:當生成對抗網絡遇上量子計算在人工智能與量子計算雙重浪潮的交匯處,量子生成對抗網絡(Quantum Generative Adversarial Networks, QGAN)正成為突破經典算力瓶頸的關鍵技術。傳統生成對抗網絡(GAN)在圖…

VBA 多個選項,將選中的選項錄入當前選中的單元格

1、使用LISTBOX插件&#xff0c;選中后回車錄入 維護好數據&#xff0c;并新增一個activeX列表框插件 Private Sub Worksheet_SelectionChange(ByVal Target As Range)If Target.Count > 1 Then Exit SubIf Target.Row > 2 And Target.Row < 10 And Target.Column 2…

【NLP輿情分析】基于python微博輿情分析可視化系統(flask+pandas+echarts) 視頻教程 - 主頁-微博點贊量Top6實現

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;最近寫了一套【NLP輿情分析】基于python微博輿情分析可視化系統(flaskpandasecharts)視頻教程&#xff0c;持續更新中&#xff0c;計劃月底更新完&#xff0c;感謝支持。今天講解主頁-微博點贊量Top6實現 視頻在線地址&…

SAP調用外部API

SAP需求將中文字符轉化為對應的拼音具體思路,由于sap中沒有將中文字符轉化為拼音的函數或方法類,則以http請求訪問外部服務器發布的API服務,然后獲取其返回值即可1.調用外部網站上提供的api缺點:免費次數有限,后需要充值這里是用www格式的json報文*&----------------------…

(12)機器學習小白入門YOLOv:YOLOv8-cls 模型微調實操

YOLOv8-cls 模型微調實操 (1)機器學習小白入門YOLOv &#xff1a;從概念到實踐 (2)機器學習小白入門 YOLOv&#xff1a;從模塊優化到工程部署 (3)機器學習小白入門 YOLOv&#xff1a; 解鎖圖片分類新技能 (4)機器學習小白入門YOLOv &#xff1a;圖片標注實操手冊 (5)機器學習小…

基于Matlab傳統圖像處理技術的車輛車型識別與分類方法研究

隨著計算機視覺和圖像處理技術的發展&#xff0c;車輛檢測與識別已經成為智能交通系統中的一個重要研究方向。傳統圖像處理方法通過對圖像進行預處理、特征提取、分類與識別&#xff0c;提供了一種無需復雜深度學習模型的解決方案。本研究基于MATLAB平臺&#xff0c;采用傳統圖…