目錄
- sentinel準備
- 流控規則 qps
- pom.xml
- apllication.yml
- 啟動類
- controller
- 查看結果
- 流控提示不太友好
- 流控規則 線程數
- 全局異常處理
- pom.xml
- application.yml
- 啟動類
- 實體類
- controller類
- 異常類
- 測試
- 關聯流控模式
- 關聯
- jmeter
- 鏈路
- service
- controller
- 代碼調整
- 流控效果
- Warm UP
- 熔斷降級規則
- 慢調用比例
- 異常比例
- 異常數
- 整合openFeign
- stock項目
- order項目
- pom.xml
- application.yml
- openFeign降級報錯友好處理
- application.yml
- 增加異常處理類
- openFeign消費者接口改造
- 熱點參數流控
- 代碼
- 系統保護規則
- cpu
- qps
- 規則持久化
- 原始模式
- 拉模式
- 推模式
- nacos設置
- pom.xml
- application.yml

sentinel官方中文文檔
sentinel準備
sentinel控制臺1.8.0
- 注意需要跟springboot cloud版本與之對應,不然會有很多問題
輸入命令
java -jar sentinel-dashboard-1.8.0.jar
- 注意默認端口是8080,很容易沖突
- 賬號和密碼都是sentinel
流控規則 qps
創建一個maven模塊,父類的包,可以查看第一篇文章
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloudalibaba</artifactId><groupId>com.cxy.springcloud</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><groupId>com.cxy.ssentinelnew</groupId><artifactId>sentinel-demo</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--sentinel啟動器--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency></dependencies>
</project>
- 導入sentinel啟動包
apllication.yml
server:port: 8010spring:application:name: sentinel-democloud:sentinel:transport:dashboard: 127.0.0.1:8080
- dashboard 是sentinel地址
- 記得啟動sentinel控制臺界面
啟動類
package com.cxy.sentinel;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @author wu* @version 1.0* @date 2024/2/26 15:52*/
@SpringBootApplication
public class StartApplication {public static void main(String[] args) {SpringApplication.run(StartApplication.class, args);}
}
controller
package com.cxy.sentinel.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author wu* @version 1.0* @date 2024/2/2 11:39*/
@RestController
@RequestMapping("/order")
public class OrderController {@RequestMapping("/add")public String add(){System.out.println("下單成功");return "Hello Feign!";}
}
查看結果
- 紅色是項目里面的服務名
- 注意:需要訪問接口后,再來查看,不然會顯示空白,先訪問下面接口
- 表示1秒鐘之內超過2次就會流控
流控提示不太友好
我們來修改一下代碼
@RequestMapping("/add")@SentinelResource(value = "add",blockHandler = "addBlockHandler")public String add(){System.out.println("下單成功");return "Hello Feign!";}public String addBlockHandler(BlockException exception){return "流控";}
- addBlockHandler這個方法,有幾點需要注意
-
- 一定是public
- 2、返回值一定跟需要做流控的那個方法一樣
- 3、BlockException 的包記得,一定是sentinel下面的
啟動后,去訪問http://localhost:8010/order/add接口,發現之前做的1秒2次流控不生效
why?
這是因為之前的規則是保存在內存中,重啟服務器后, 就不存在,需要重新加一次
再來訪問一下http://localhost:8010/order/add
-返回狀態碼也變成200,實際使用過程中,返回值,我們肯定會封裝成一個返回類包裝一下的
流控規則 線程數
package com.cxy.sentinel.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.concurrent.TimeUnit;/*** @author wu* @version 1.0* @date 2024/2/2 11:39*/
@RestController
@RequestMapping("/order")
public class OrderController {/*** 流控----qps* @return*/@RequestMapping("/add")@SentinelResource(value = "add",blockHandler = "addBlockHandler")public String add(){System.out.println("下單成功");return "Hello Feign!";}public String addBlockHandler(BlockException exception){return "流控";}/*** 流控--線程控制方法* @return* @throws InterruptedException*/@RequestMapping("/addThread")@SentinelResource(value = "addThread",blockHandler = "addBlockHandler")public String addThread() throws InterruptedException {System.out.println("下單成功");TimeUnit.SECONDS.sleep(5);return "Hello Feign!"+Thread.currentThread().getName();}
}
- addThread 這個方法是新增加的,其他的代碼,跟qps的代碼一樣
- 增加一個延遲,是為了測試方便測試線程數
啟動兩個瀏覽器,才能測出線程數流控的效果
- 搞不清楚為什么,同一個瀏覽器,我看了一下線程名稱也不一樣,為什么不走流控
全局異常處理
在之前寫的代碼中,會存在一個問題,每一個需要流控、降級處理的方法,都需要加上@sentinelResource注解,在家一個異常處理的方式,用起來什么不方便,看起來也十分的別扭。
那有全局處理sentinel異常的方案,有的
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloudalibaba</artifactId><groupId>com.cxy.springcloud</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><groupId>com.cxy.ssentinelnew</groupId><artifactId>sentinel-demo</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--sentinel啟動器--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version></dependency></dependencies>
</project>
application.yml
server:port: 8010spring:application:name: sentinel-democloud:sentinel:transport:dashboard: 127.0.0.1:8080
啟動類
package com.cxy.sentinel;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @author wu* @version 1.0* @date 2024/2/26 15:52*/
@SpringBootApplication
public class StartApplication {public static void main(String[] args) {SpringApplication.run(StartApplication.class, args);}
}
實體類
package com.cxy.sentinel.entity;public enum ResponseCode {SUCCESS(200, "success"),FAILURE(201, "failure"),EXCEPTION(500, "exception"),INVALID_TOKEN(501, "invalidToken");private int code;private String message;ResponseCode(int code, String message) {this.code = code;this.message = message;}public int getCode() {return code;}public String getMessage(){return message;}
}package com.cxy.sentinel.entity;import lombok.Data;import java.io.Serializable;@Data
public class ResponseResult<T> implements Serializable {private static final long serialVersionUID = 1L;private int code;private String message;private T payload;public ResponseResult() {this.code = ResponseCode.SUCCESS.getCode();this.message = ResponseCode.SUCCESS.getMessage();}public ResponseResult(int code, String message) {this.code = code;this.message = message;}public ResponseResult(int code, String message, T payload) {this.code = code;this.message = message;this.payload = payload;}public static <T> ResponseResult<T> SUCCESS() {return new ResponseResult<>(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getMessage(), null);}public static <T> ResponseResult<T> SUCCESS(T payload) {return new ResponseResult<>(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getMessage(), payload);}public static <T> ResponseResult<T> FAILURE(String message) {return new ResponseResult<>(ResponseCode.FAILURE.getCode(), message);}public static <T> ResponseResult<T> EXCEPTION(String message) {return new ResponseResult<>(ResponseCode.EXCEPTION.getCode(), message, null);}public static <T> ResponseResult<T> EXCEPTION(ResponseCode resCode) {ResponseResult<T> resResult = new ResponseResult<>();resResult.setCode(resCode.getCode());resResult.setMessage(resCode.getMessage());return resResult;}public static <T> ResponseResult<T> INVALID_TOKEN(String message) {return new ResponseResult<>(ResponseCode.INVALID_TOKEN.getCode(), message);}
}
- 返回輔助類
controller類
package com.cxy.sentinel.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.cxy.sentinel.entity.ResponseResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.concurrent.TimeUnit;/*** @author wu* @version 1.0* @date 2024/2/2 11:39*/
@RestController
@RequestMapping("/order")
public class OrderController {/*** 流控--異常處理* @return* @throws InterruptedException*/@RequestMapping("/addException")public ResponseResult addException() throws InterruptedException {System.out.println("流控異常處理!");return ResponseResult.SUCCESS();}
}
異常類
package com.cxy.sentinel.config;import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.cxy.sentinel.entity.ResponseResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component // 注冊為Bean 讓Spring管理
public class SentinelExceptionHandler implements BlockExceptionHandler {@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {String msg = "未知異常";int status = 429;// 通過判斷異常的類型 來判斷到底是限流還是熔斷降級還是授權限制if (e instanceof FlowException) {msg = "請求被限流了";} else if (e instanceof ParamFlowException) {msg = "請求被熱點參數限流";} else if (e instanceof DegradeException) {msg = "請求被降級了";} else if (e instanceof AuthorityException) {msg = "沒有權限訪問";status = 401;}response.setContentType("application/json;charset=utf-8");response.setCharacterEncoding("utf-8");response.setStatus(status);new ObjectMapper().writeValue(response.getWriter(), ResponseResult.EXCEPTION(msg));}
}
- 試過用全局注解的方式來處理sentinel的異常,不知道為什么捕獲不到,有知道的朋友可以解答一下,網上我看也有類似的方法,但是,測試過不行
測試
先訪問http://localhost:8010/order/addException接口,再增加一條流控為1的規則,表示1秒鐘之內只能訪問一次
- 出現這個,表示設置成功
關聯流控模式
流控模式,分為三種,直接、關聯、鏈路
關聯
類似場景,12306,如果下單人數過多,點擊查詢票的時候,就顯示服務正在繁忙
當兩個資源存在爭取時,就會存在關聯,例如,數據庫的某個表的讀寫,寫多,讀少等等
/*** 關聯流控模式* @return*/@RequestMapping("/addOrder")public String addOrder(){System.out.println("下單成功");return "生成訂單!";}/*** 關聯流控模式* @return*/@RequestMapping("/get")public String get(){System.out.println("查詢訂單");return "查詢訂單!";}
- 在全局異常處理的controller類中,增加如上代碼
啟動項目,增加流控,點擊關聯,訪問http://localhost:8010/order/get 查詢接口時,關聯下單接口,意思是,下單接口訪問過多時,查詢會流控
為了方便測試,需要借助一個工具jmeter用來模擬發送請求
jmeter
jmeter測試工具
- 表示100秒內,300個線程,1秒至少3次
訪問http://localhost:8010/order/get接口
鏈路
跟全局異常處理一樣的代碼,增加如下代碼
service
package com.cxy.sentinel.service;/*** @author wu* @version 1.0* @date 2024/2/28 14:26*/
public interface OrderService {/*** 查詢用戶* @return*/public String getUser();
}package com.cxy.sentinel.service;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.stereotype.Service;/*** @author wu* @version 1.0* @date 2024/2/28 14:27*/
@Service
public class OrderServiceImpl implements OrderService{@Override@SentinelResource(value = "getUser")public String getUser() {return "查詢用戶";}
}
- 增加SentinelResource注解,說明是sentinel資源,在界面就可以進行設置
controller
-以前的controller增加如下代碼
@Autowiredprivate OrderService orderService;//關聯流控 訪問/add 觸發/get@RequestMapping("/test1")public String test1(){return orderService.getUser();}//關聯流控 訪問/add 觸發/get@RequestMapping("/test2")public String test2(){return orderService.getUser();}
訪問http://localhost:8010/order/test2,設置流控
繼續訪問http://localhost:8010/order/test2,三次,出現如下畫面,說明,流控成功
== 為什么報錯?==
這是因為service類里面增加@SentinelResource后,會導致,對應的接口,不走全局異常,只能自定義異常來處理
代碼調整
- 配置里面需要調整一下這個
package com.cxy.sentinel.service;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;/*** @author wu* @version 1.0* @date 2024/2/28 14:27*/
@Service
public class OrderServiceImpl implements OrderService{@Override@SentinelResource(value = "getUser",blockHandler="getUserHandler")public String getUser() {return "查詢用戶";}public String getUserHandler(BlockException ex) {return "流控用戶";}
}
訪問http://localhost:8010/order/test2,如下圖,說明配置成功
總結起來:
兩個坑點:
- 配置里面application.yml配置里面需要設置成false, 全局流控異常處理不生效,需要自定義異常處理
流控效果
- 流控效果分為三種
Warm UP
有一個預熱的過程,長期處在一個低流量過程,突然一下子流量狂飆,很容易導致系統出問題,所以,通過冷啟動,讓通過的流量,緩慢的增加,在一定時間內,加到對應的閾值
設置快速失敗為5
- 設置1秒10次,循環4次
- 定時休息5秒
- 設置http請求
-通過上圖可以發現,藍色的線和綠色的線有重合的地方,我們的目標就是讓藍色的線,變平緩
- 設置成排隊等待5秒,效果如下圖
- 標紅的地方,有空閑,說明,我們之前在線程哪里設置的,1秒10次,對服務器的壓力不大
熔斷降級規則
說到熔斷,降級,我想大部分的人,腦海中,頓時就飄過hystrix,今天主要是看看sentinel的熔斷
慢調用比例
- 訪問/order/addThread資源時,如果在1000毫秒內,請求數量超過5,并且這些數量中超過1000毫秒的請求數量的比例超過0.1則熔斷1秒
代碼和前面一樣,在之前的基礎上,增加
/*** 熔斷降級規則,----慢調用比例* @return* @throws InterruptedException*/@RequestMapping("/addLevel")public String addLevel() throws InterruptedException {System.out.println("下單成功");TimeUnit.SECONDS.sleep(2);return "Hello Feign!"+Thread.currentThread().getName();}
三部曲:
1、訪問接口http://localhost:8010/order/addLevel
2、添加熔斷規則
3、jemter壓測
再去訪問,接口被熔斷了
- 熔斷后,只有有一次不是慢查詢,就會恢復正常
異常比例
熔斷策略異常比例是以請求異常數量的比例作為閾值,當單位統計時長(statIntervalMs)內請求數大于設置的最小請求數,并且異常請求數的比例大于比例閾值,則接下來的請求會自動熔斷,熔斷時間為設置的熔斷時長。經過熔斷時長后熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若在HALF-OPEN狀態下有一個請求正常響應 則結束熔斷,否則繼續熔斷。
先訪問http://localhost:8010/order/err
- 從第六次開始,就熔斷降級
異常數
- 連續訪問3次后,服務就進行了熔斷,會熔斷10s
整合openFeign
openFeign代碼
在這個基礎上做測試
- 主要是涉及兩個項目
stock項目
/*** 增加異常* @return*/@RequestMapping("/reduct1")public String reduct1(){int a = 1/0;System.out.println("扣減庫存!");return "扣減庫存"+port;}
order項目
/*** 產生異常* @return*/@RequestMapping("/reduct1")public String reduct1(){String msg = stockFeignService.reduct1();return "Hello Feign!"+msg;}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloudalibaba</artifactId><groupId>com.cxy.springcloud</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>order</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--Nacos做配置中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--添加openfeign依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><!--sentinel啟動器--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency></dependencies></project>
- 添加sentinel依賴
application.yml
- 紅色部分,是新增代碼
server:port: 8015spring:application:name: order-servicecloud:nacos:server-addr: 127.0.0.1:8848discovery:name: nacospassword: nacosnamespace: publicloadbalancer:ribbon:enabled: falsesentinel:transport:dashboard: 127.0.0.1:8080web-context-unify: false #默認將調用鏈路收起來####設置springboot級別
logging:level:com.cxy.order.feign.StockFeignService: debug
feign:client:config:stock-servic: ###對應微服務###鏈接超時時間 默認2sconnectTimeout: 5000### 請求處理超時時間 默認5sreadTimeout: 10000##添加feign對sentinel的兼容sentinel:enabled: true
訪問http://localhost:8015/order/reduct1,直接報錯,有點不友好
openFeign降級報錯友好處理
1、增加openFeign對sentinel的兼容
application.yml
feign:client:config:stock-servic: ###對應微服務###鏈接超時時間 默認2sconnectTimeout: 5000### 請求處理超時時間 默認5sreadTimeout: 10000##添加feign對sentinel的兼容sentinel:enabled: true
增加異常處理類
package com.cxy.order.feign;import org.springframework.stereotype.Component;/*** @author wu* @version 1.0* @date 2024/2/21 17:54*/
@Component
public class StockFeignServiceFallback implements StockFeignService{@Overridepublic String reduct() {return "降級";}@Overridepublic String reduct1() {return "降級";}
}
- 返回異常處理提示
openFeign消費者接口改造
- 跟以前的hystric一樣的寫法
啟動order項目,再來訪問
到這里,openFeign降級就完成咯。
熱點參數流控
熱點即經常訪問的數據,很多時候,我們需要針對一些頻率很高的數據,對其使用限制。
代碼
/*** 熱點規則,必須使用@SentinelResource** @return*/@RequestMapping("/get/{id}")@SentinelResource(value = "getById", blockHandler = "HotBlockHandler")public String getById(@PathVariable("id") Integer id) {System.out.println("正常訪問:" + id);return "正常訪問:" + id;}public String HotBlockHandler(@PathVariable("id") Integer id, BlockException e) {return "熱點異常處理" + id;}
- 還是在之前項目中,進行更改(Order項目)
- 單機閾值遵循一個原則,熱點參數和普通參數,誰多,誰就是設置成單機閾值
例如: 某個商品平臺,今天晚上進行白酒秒殺,其他的商品沒有活動,就可以把普通商品設置成單機閾值,白酒作為參數特殊設置。 - 上面的效果,就是普通的商品,能1秒訪問10次,商品id為1的,1秒鐘只能訪問2次。
直接訪問http://localhost:8015/order/get/1 三次
系統保護規則
系統保護規則是從應用級別的入口流量進行控制,從單臺機器的總體 Load、RT、線程數、入口 QPS 和CPU使用率監控應用數據,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。
cpu
- sentinel剛開始整的那個項目代碼里面進行測試
package com.cxy.sentinel.config;import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.cxy.sentinel.entity.ResponseResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component // 注冊為Bean 讓Spring管理
public class SentinelExceptionHandler implements BlockExceptionHandler {@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {String msg = "未知異常";int status = 429;// 通過判斷異常的類型 來判斷到底是限流還是熔斷降級還是授權限制if (e instanceof FlowException) {msg = "請求被限流了";} else if (e instanceof ParamFlowException) {msg = "請求被熱點參數限流";} else if (e instanceof DegradeException) {msg = "請求被降級了";}else if (e instanceof SystemBlockException){msg = "系統規則保護";} else if (e instanceof AuthorityException) {msg = "沒有權限訪問";status = 401;}response.setContentType("application/json;charset=utf-8");response.setCharacterEncoding("utf-8");response.setStatus(status);new ObjectMapper().writeValue(response.getWriter(), ResponseResult.EXCEPTION(msg));}
}
- 之前的歷史代碼,少了一個SystemBlockException異常else判斷的代碼,這里補一下
- 為了方便測試,cpu使用率的值是0-1,所以這里的0.01表示,只要cpu超過1,就會走系統保護
qps
這里的1,表示所有接口的平均qps,而不是某個接口的閾值
規則持久化
原始模式
存在內存中,開發環境測試使用,服務一重啟,配置就消失
拉模式
pull模式的數據源(如本地文件、RDBMS等)一般是可寫入的。使用時需要在客戶端注冊數據源:將對應的讀數據源注冊至對應的 RuleManager,將寫數據源注冊至transport的WritableDataSourceRegistry中。
推模式
生產環境下一般更常用的是push模式的數據源。對于push模式的數據源,如遠程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不應由Sentinel客戶端進行,而應該經控制臺統一進行管理,直接進行推送,數據源僅負責獲取配置中心推送的配置并更新到本地。因此推送規則正確做法應該是配置中心控制臺/Sentinel控制臺 → 配置中心 → Sentinel數據源 → Sentinel,而不是經Sentinel數據源推送至配置中心。這樣的流程就非常清晰了:
nacos設置
- 先新增nacos對應的配置
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloudalibaba</artifactId><groupId>com.cxy.springcloud</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>order</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--Nacos做配置中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--添加openfeign依賴--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><!--sentinel啟動器--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!--sentinel配置中心控制臺推送--><!--以nacos作為sentinel數據源的依賴--><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency></dependencies></project>
- 在以前的基礎上,新增了該接口
application.yml
server:port: 8015spring:application:name: order-servicecloud:
# nacos:
# server-addr: 127.0.0.1:8848
# discovery:
# name: nacos
# password: nacos
# namespace: publicloadbalancer:ribbon:enabled: falsesentinel:transport:dashboard: 127.0.0.1:8080web-context-unify: false #默認將調用鏈路收起來datasource:flow-ds:nacos:server-addr: 127.0.0.1:8848username: nacospassword: nacosnamespace: publicdataId: ${spring.application.name}-flowgroupId: DEFAULT_GROUPdata-type: jsonrule-type: flow####設置springboot級別
logging:level:com.cxy.order.feign.StockFeignService: debug
feign:client:config:stock-servic: ###對應微服務###鏈接超時時間 默認2sconnectTimeout: 5000### 請求處理超時時間 默認5sreadTimeout: 10000##添加feign對sentinel的兼容sentinel:enabled: true
- flow-ds 是隨便寫的,其他的有講究
支持很多的數據庫,這里我們使用的nacos,所以用nacos的配置
ctrl+shift+\ 輸入DataSourcePropertiesConfiguration,找到nacois得代碼,打開
- 可以進行參考配置
有個問題:不知道為什么,需要先調用一次服務的接口后,才能看到,我們之前在nacos里面的配置,同步到sentinel中,懷疑是不是緩存
到這里我們就實現sentinel配置持久化了
存在幾個問題:
1.在nacos配置很復雜
2、在sentinel中變更后,怎么同步到nacos里面來,有知道朋友,可以留言評論