引入依赖
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
创建REST接口,通过@SentinelResource配置限流保护资源
@RestController
@RequestMapping("api/testSentinel")
public class TestSentinelController {
@SentinelResource(value = "test",blockHandler = "handlerExcption1")
@GetMapping()
public Map<String,String> testSentinel(String name) throws InterruptedException {
TimeUnit.SECONDS.sleep(2);
HashMap<String, String> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("msg",name);
return objectObjectHashMap;
}
public static Map<String,String> handlerExcption1(String name,BlockException exception){
HashMap<String, String> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("msg","禁止访问");
FlowRule flowRule = new FlowRule();
return objectObjectHashMap;
}
}
启动 sentinel 服务
在 application.yml 中加入如下配置
spring:
cloud:
sentinel:
# 取消控制台懒加载
eager: true
transport:
# 控制台地址
dashboard: 127.0.0.1:8858
启动项目
通过 sentinel Dashboard 配置流控规则

使用 apiFox 或者其他工具测试

在默认情况下 ,URL 触发限流会直接返回
大多数情况下们都采用JSON格式的数据,所以如果希望修改触发限流之后的返回结果形式,则可以通过自定义异常来处理,实现BlockExceptionHandler并且重写 handle方法
@Service
public class CustomerUrlBlockerHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
httpServletResponse.setHeader("Content-Type","application/json;charset=UTF-8");
String message = "{\"code\": 999,\"msg\":\"访问人数过多\"}";
httpServletResponse.getWriter().write(message);
}
}
还有一种 我们可以通过 以下配置,跳转到一个降级页面
spring.cloud.semtinel.servlet.block-page={url}
Sentinel 中的 CommonFilter 会把每个不同的url都作为不同的资源来处理
@GetMapping("user/{id}")
public Map<String,String> testSentinel1(@PathVariable("id") Long id) throws InterruptedException {
HashMap<String, String> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("msg","hello");
return objectObjectHashMap;
}
上面的这两个写法会导致两个问题
针对于上边第一个问题 我们可以通过UrlCleaner 来实现资源清洗
@Service
public class CustomerUrlCleaner implements UrlCleaner {
@Override
public String clean(String url) {
if(StringUtils.isEmpty(url)) {
return url;
}
if(url.startsWith("/clean/")){
return "/clean/*";
}else {
return url;
}
}
}
通过 springBoot 接入Sentinel DashBoard所配置的的流控规则,都是保存在内存中的,一旦应用重启,这些规则都会被清除,为了解决这个问题,Sentinel提供了动态数据源支持
添加Nacos数据源依赖包
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
在 Naocs的配置中心配置数据源
spring:
cloud:
sentinel:
# 取消控制台懒加载
eager: true
transport:
# 控制台地址
dashboard: 127.0.0.1:8858
datasource:
- nacos:
server-addr: 127.0.0.1:8848
data-id: ${spring.application.name}-sentinel
namespace: zcctConfig
group-id: sentinel-data
data-type: json
rule-type: flow
增加流控配置文件

启动项目测试
可以看到Sentinel控制台中增加了一个流控规则,当我们在Nacos中更改该规则时,可以同步到Sentinel DashBoard中

Nacos 虽然被作为 ”DataSource“ , 但实际上在这里仍然是配置中心的角色,开发者可以在Nacos控制台上动态修改流控规则并实现规则同步,但在 Sentinel Dashboard 中修改或新增规则后不会持久化到配置中心。
