目錄
一、Sentinel下載并運行
二、創建8401微服務整合Sentinel
三、流控規則?
3.1、直接模式?
3.2、關聯模式
3.3、鏈路模式?
3.3.1、修改8401代碼?
?3.3.2、創建流控模式
3.4、Warm UP(預熱)??編輯
3.5、排隊等待
四、熔斷規則
4.1、慢調用比例?
4.2、異常比例?
4.3、異常數
?五、@SentinelResource注解
5.1、按照rest地址限流+默認限流返回??編輯
5.2、按SentinelResource資源名稱限流+自定義限流返回
5.3、按SentinelResource資源名稱限流+自定義限流返回+服務降級處理
六、熱點規則?
6.1、參數例外項?
七、授權規則??編輯
八、規則持久化
九、整合Openfeign
十、整合Gateway?
一、Sentinel下載并運行
運行命令:java -jar sentinel-dashboard-1.8.7.jar
訪問界面:
二、創建8401微服務整合Sentinel
導入相關pom及yml文件配置
<dependencies><!--SpringCloud alibaba sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!--nacos-discovery--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- 引入自己定義的api通用包 --><dependency><groupId>com.cjc.cloud</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency><!--SpringBoot通用依賴模塊--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version><scope>provided</scope></dependency><!--test--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
server:port: 8401spring:application:name: cloudalibaba-sentinel-servicecloud:nacos:discovery:server-addr: localhost:8848 #Nacos服務注冊中心地址sentinel:transport:dashboard: localhost:8080 #配置Sentinel dashboard控制臺服務地址port: 8719 #默認8719端口,假如被占用會自動從8719開始依次+1掃描,直至找到未被占用的端口
測試代碼:
@SpringBootApplication
@EnableDiscoveryClient
public class Main8401 {public static void main(String[] args) {SpringApplication.run(Main8401.class,args);}
}
@RestController
public class FlowLimitController {@GetMapping("/testA")public String testA(){return "------testA";}@GetMapping("/testB")public String testB(){return "------testB";}
}
三、流控規則?
3.1、直接模式?
?默認使用
3.2、關聯模式
3.3、鏈路模式?
3.3.1、修改8401代碼?
sentinel:transport:dashboard: localhost:8080 #配置Sentinel dashboard控制臺服務地址port: 8719 #默認8719端口,假如被占用會自動從8719開始依次+1掃描,直至找到未被占用的端口web-context-unify: false # controller層的方法對service層調用不認為是同一個根鏈路
@Service
public class FlowLimitService {@SentinelResource(value = "common")public void common(){System.out.println("------FlowLimitService come in");}
}
@Autowiredprivate FlowLimitService flowLimitService;@GetMapping("/testC")public String testC(){flowLimitService.common();return "------testC";}@GetMapping("/testD")public String testD(){flowLimitService.common();return "------testD";}
?3.3.2、創建流控模式
3.4、Warm UP(預熱)?
3.5、排隊等待
?
四、熔斷規則
4.1、慢調用比例?
?
進行壓測:
?
4.2、異常比例?
??
4.3、異常數
?
?五、@SentinelResource注解
?SentinelResource是一個流量防衛防護組件注解, 哨兵資源是一個流量防衛防護組件注解,用于指定防護資源,對配置的資源進行流量控制、熔斷降級等功能。
5.1、按照rest地址限流+默認限流返回?
測試訪問:
?
5.2、按SentinelResource資源名稱限流+自定義限流返回
測試代碼:
@GetMapping("/rateLimit/byResource")@SentinelResource(value = "byResourceSentinelResource",blockHandler = "handleException")public String byResource(){return "按資源名稱SentinelResource限流測試OK";}public String handleException(BlockException exception){return "服務不可用@SentinelResource啟動"+"\t"+"o(╥﹏╥)o";}
?
測試訪問:
?
5.3、按SentinelResource資源名稱限流+自定義限流返回+服務降級處理
@GetMapping("/rateLimit/doAction/{p1}")@SentinelResource(value = "doActionSentinelResource",blockHandler = "doActionBlockHandler", fallback = "doActionFallback")public String doAction(@PathVariable("p1") Integer p1) {if (p1 == 0){throw new RuntimeException("p1等于零直接異常");}return "doAction";}public String doActionBlockHandler(@PathVariable("p1") Integer p1,BlockException e){log.error("sentinel配置自定義限流了:{}", e);return "sentinel配置自定義限流了";}public String doActionFallback(@PathVariable("p1") Integer p1,Throwable e){log.error("程序邏輯異常了:{}", e);return "程序邏輯異常了"+"\t"+e.getMessage();}
?
測試結果:
?
六、熱點規則?
@GetMapping("/testHotKey")@SentinelResource(value = "testHotKey",blockHandler = "dealHandler_testHotKey")public String testHotKey(@RequestParam(value = "p1",required = false) String p1,@RequestParam(value = "p2",required = false) String p2){return "------testHotKey";}public String dealHandler_testHotKey(String p1,String p2,BlockException exception){return "-----dealHandler_testHotKey";}
?
測試結果:
?
6.1、參數例外項?
?
七、授權規則?
測試訪問:
?
八、規則持久化
添加pom依賴
<!--SpringCloud ailibaba sentinel-datasource-nacos --><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency>
?修改yml
spring:application:name: cloudalibaba-sentinel-servicecloud:nacos:discovery:server-addr: localhost:8848 #Nacos服務注冊中心地址sentinel:transport:dashboard: localhost:8080 #配置Sentinel dashboard控制臺服務地址port: 8719 #默認8719端口,假如被占用會自動從8719開始依次+1掃描,直至找到未被占用的端口web-context-unify: false # controller層的方法對service層調用不認為是同一個根鏈路datasource:ds1:nacos:server-addr: localhost:8848dataId: ${spring.application.name}groupId: DEFAULT_GROUPdata-type: jsonrule-type: flow # com.alibaba.cloud.sentinel.datasource.RuleType
在nacos服務配置中進行配置
?
測試:
?
九、整合Openfeign
修該9001服務提供者pom及yml
<!--openfeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--alibaba-sentinel--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
spring:application:name: nacos-payment-providercloud:nacos:discovery:server-addr: localhost:8848 #配置Nacos地址sentinel:transport:dashboard: localhost:8080 #配置Sentinel dashboard控制臺服務地址port: 8719 #默認8719端口,假如被占用會自動從8719開始依次+1掃描,直至找到未被占用的端口
測試代碼:
@GetMapping("/pay/nacos/get/{orderNo}")@SentinelResource(value = "getPayByOrderNo",blockHandler = "handlerBlockHandler")public ResultData getPayByOrderNo(@PathVariable("orderNo") String orderNo){//模擬從數據庫查詢出數據并賦值給DTOPayDTO payDTO = new PayDTO();payDTO.setId(1024);payDTO.setOrderNo(orderNo);payDTO.setAmount(BigDecimal.valueOf(9.9));payDTO.setPayNo("pay:"+ IdUtil.fastUUID());payDTO.setUserId(1);return ResultData.success("查詢返回值:"+payDTO);}public ResultData handlerBlockHandler(@PathVariable("orderNo") String orderNo, BlockException exception){return ResultData.fail(ReturnCodeEnum.RC500.getCode(),"getPayByOrderNo服務不可用," +"觸發sentinel流控配置規則"+"\t"+"o(╥﹏╥)o");}
?遠程調用測試代碼:
@FeignClient(value = "nacos-payment-provider",fallback = PayFeignSentinelApiFallBack.class)
public interface PayFeignSentinelApi {@GetMapping("/pay/nacos/get/{orderNo}")public ResultData getPayByOrderNo(@PathVariable("orderNo") String orderNo);
}
@Component
public class PayFeignSentinelApiFallBack implements PayFeignSentinelApi{@Overridepublic ResultData getPayByOrderNo(String orderNo) {return ResultData.fail(ReturnCodeEnum.RC500.getCode(),"對方服務宕機或不可用,FallBack服務降級o(╥﹏╥)o");}
}
修改80消費者yml
# 激活Sentinel對Feign的支持
feign:sentinel:enabled: true
@Resourceprivate PayFeignSentinelApi payFeignSentinelApi;@GetMapping(value = "/consumer/pay/nacos/get/{orderNo}")public ResultData getPayByOrderNo(@PathVariable("orderNo") String orderNo){return payFeignSentinelApi.getPayByOrderNo(orderNo);}
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class NFMain80 {public static void main(String[] args) {SpringApplication.run(NFMain80.class,args);}
}
啟動80服務報錯
?
修改springcloud版本,也可以下調springboot版本
?
測試結果:
?
?
十、整合Gateway?
?新建9528微服務并導入相關pom與yml
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-transport-simple-http</artifactId><version>1.8.6</version></dependency><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-spring-cloud-gateway-adapter</artifactId><version>1.8.6</version></dependency><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version><scope>compile</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
server:port: 9528spring:application:name: cloudalibaba-sentinel-gateway # sentinel+gataway整合Casecloud:nacos:discovery:server-addr: localhost:8848gateway:routes:- id: pay_routh1 #pay_routh1 #路由的ID(類似mysql主鍵ID),沒有固定規則但要求唯一,建議配合服務名uri: http://localhost:9001 #匹配后提供服務的路由地址predicates:- Path=/pay/** # 斷言,路徑相匹配的進行路由
測試代碼:
@SpringBootApplication
@EnableDiscoveryClient
public class Main9528 {public static void main(String[] args) {SpringApplication.run(Main9528.class,args);}
}
@Configuration
public class GatewayConfiguration {private final List<ViewResolver> viewResolvers;private final ServerCodecConfigurer serverCodecConfigurer;public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer){this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);this.serverCodecConfigurer = serverCodecConfigurer;}@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {// Register the block exception handler for Spring Cloud Gateway.return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);}@Bean@Order(-1)public GlobalFilter sentinelGatewayFilter() {return new SentinelGatewayFilter();}@PostConstruct //javax.annotation.PostConstructpublic void doInit() {initBlockHandler();}//處理/自定義返回的例外信息private void initBlockHandler() {Set<GatewayFlowRule> rules = new HashSet<>();rules.add(new GatewayFlowRule("pay_routh1").setCount(2).setIntervalSec(1));GatewayRuleManager.loadRules(rules);BlockRequestHandler handler = new BlockRequestHandler() {@Overridepublic Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable t) {Map<String,String> map = new HashMap<>();map.put("errorCode", HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase());map.put("errorMessage", "請求太過頻繁,系統忙不過來,觸發限流(sentinel+gataway整合Case)");return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(map));}};GatewayCallbackManager.setBlockHandler(handler);}
}
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?