Sentinel限流相关测试代码【我】
controller代码:
package com.mt.cousumer.sentineltest.controller; import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.mt.cousumer.sentineltest.service.MyExtBlockHandler; import com.mt.cousumer.sentineltest.service.TestSenService; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @Slf4j @RestController public class TestSenController { @Resource private TestSenService sentinelTestService; // 无限流配置的请求 @GetMapping("/s") public String s(){ String s = "正常返回s,无限流配置,不限流"; return s; } // 限流,使用全局限流返回逻辑 @GetMapping("/s1") public String s1(){ return "正常返回s1"; } // 限流,使用单独配置的特殊限流后处理逻辑 @GetMapping("/s2") @SentinelResource(value = "doSomething",blockHandler = "blockDoSomething") public String s2(){ return "正常返回s2"; } // 针对限流资源doSomething的特殊限流后返回逻辑【此方法方法名和原方法上的blockHandler=""注解属性值一致,同时要和原方法返回列表、参数值一致,额外增加BlockException参数】 public String blockDoSomething(BlockException e){ return "s2被特殊限流了"; } // 非url限流,调用服务类,在服务方法上设置限流【注意:这种使用方式就不要配置/s3为资源的url限流,否则被调用方法的限流就会失效】 @GetMapping("/s3") public String s3(){ String s = sentinelTestService.doSomething2(); return s; } // 限流,使用单独配置的特殊限流后处理逻辑,处理逻辑在其他类里 @GetMapping("/s4") @SentinelResource(value = "doSomething4",blockHandlerClass= MyExtBlockHandler.class ,blockHandler = "blockDoSomething4") public String s4(){ return "正常返回s4"; } // 限流,使用单独配置的特殊限流后处理逻辑,处理逻辑在其他类里 @GetMapping("/s5") // 经测试热点限流必须用 @SentinelResource 注解定义资源,直接用url请求/s5无效, // 而且热点限流不能使用公共配置的限流后处理逻辑,如果没有设置单独的自定义限流后处理方法,会直接返回固定的异常信息(非我们自定义的url限流异常信息) @SentinelResource(value = "hot",blockHandler = "hotBlockHandler") public String s5(@RequestParam(required = false) String a,@RequestParam(required = false) String b){ return a+"-"+b; } public String hotBlockHandler(@RequestParam(required = false) String a,@RequestParam(required = false) String b,BlockException e){ return a+"-"+b+"被热点限流"; } } /** [{ "resource": "/s1", "grade": 1, "count": 1, "strategy": 0 }, { "resource": "doSomething", "grade": 1, "count": 1, "strategy": 0 }, { "resource": "doSomething2", "grade": 1, "count": 1, "strategy": 0 }, { "resource": "doSomething4", "grade": 1, "count": 1, "strategy": 0 }] */
service:
package com.mt.cousumer.sentineltest.service; import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler; import com.alibaba.csp.sentinel.slots.block.BlockException; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //自定义一个默认sentinel异常处理类 @Service public class MyUrlBlockHandler implements BlockExceptionHandler { @Override public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, BlockException e) throws Exception { response.setHeader("Content-Type","application/json;charset=UTF-8"); String message = "{\"code\":999,\"msg\":\"默认全局限流返回:访问人数过多\"}"; // response.setCharacterEncoding("utf-8"); // response.setHeader("Content-Type", "application/json;charset=utf-8"); // response.setContentType("application/json;charset=utf-8"); response.getWriter().write(message); } }
package com.mt.cousumer.sentineltest.service; import com.alibaba.csp.sentinel.slots.block.BlockException; //sentinel的限流、熔断异常后的逻辑类 public class MyExtBlockHandler { // 限流后的返回逻辑【注意:这个方法必须用static修饰,否则加载不到】 public static String blockDoSomething4(BlockException e){ return "doSomething4被限流了,使用外部类方法"; } }
package com.mt.cousumer.sentineltest.service; import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import org.springframework.stereotype.Service; //在service方法上设置限流 @Service public class TestSenService { @SentinelResource(value = "doSomething2",blockHandler = "blockDoSomething2") public String doSomething2(){ return "service方法doSomething2正常返回"; } // 限流后的返回逻辑 public String blockDoSomething2(BlockException e){ return "service方法doSomething2被限流了"; } }
限流相关pom:
<!--sentineltest 断路器 & 流量监控--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-parameter-flow-control</artifactId> </dependency>
yml配置:
server:
port: 8084
spring:
# profiles:
# active: dev
application:
name: mt-consumer
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
# file-extension: yaml
# file-extension: properties
# prefix: myNacosConfig
# prefix: example
sentinel:
eager: true # 使用饿汉模式(关闭懒加载,懒加载模式下只有访问的时候,才能在监控页面看到)
transport:
dashboard: 127.0.0.1:8080 # dashboard 地址,sentineltest-dashboard 启动后默认为 8080
datasource:
- nacos:
server-addr: 127.0.0.1:8848
# 这里的data-id 要和nacos里要使用的配置的data-id一样,否则加载不到动态配置
# data-id: sentinel-dynamic1
data-id: ${spring.application.name}-flow-rules
# group-id: DEFAULT_GROUP
group-id: SENTINEL_GROUP
data-type: json
rule-type: flow
#此跳转异常页面和实现BlockExceptionHandler接口自定义只能用一个,如果实现了接口,则此处的配置不生效
blockPage: https://www.baidu.com/
#info: aaa
#dubbo:
# protocol:
# name: dubbo
# port: -1
# scan:
# base-packages: com.mt.consumer.**
# cloud:
# subscribed-services: '*'
# consumer:
# check: false
# registry:
# address: nacos://127.0.0.1:8848