前言:限流的关键有两点:
1.生成令牌
2.抢令牌
step1:pom.xml配置
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.3</version>
</dependency>
step2: 生成令牌:
@SpringBootApplication
@EnableZuulProxy
public class CloudZuulApplication {
public static void main(String[] args) {
initQPS();//sentinel初始化
SpringApplication.run(CloudZuulApplication.class, args);
}
private static void initQPS() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("SentinelService.success");//需要保护的资源名称 方式1
// rule.setResource("helloworld");//需要保护的资源名称 方式2
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);//限流的类型
rule.setCount(5);//设置最大并发数为5
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
/**
* 在执行之前进行限流判断,在捕获异常的时候,
* 会根据异常类型判断是调用fallback方法还是调用block handler方法
* @return
*/
@Bean
public SentinelResourceAspect sentinelResourceAspect(){
return new SentinelResourceAspect();
}
}
step3: 使用令牌以下方式二选一
方式1:value一般为类名+方法名,blockHandler为限流后的访问的方法
@Service
public class SentinelService {
@SentinelResource(value = "SentinelService.success", blockHandler = "fail")
public String success() {
System.out.println("success...请求正常");
return "success";
}
public String fail(BlockException e) {
System.out.println("fail...阻塞");
return "fail";
}
}
方式2:通过自定义过滤器,
@Component
public class SentinelFilter extends ZuulFilter {
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return -100;
}
@Override
public boolean shouldFilter() {
return false;
}
@Override
public Object run() throws ZuulException {
// TODO: 2022/3/30 限流的业务逻辑,使用令牌
Entry entry = null;
try {
entry = SphU.entry("helloword");
//业务逻辑
System.out.println("正常请求");
} catch (BlockException e) {
System.out.println("阻塞了");
RequestContext.getCurrentContext().set("limit", false);
} finally {
if (entry != null) {
entry.exit();
}
}
return null;
}
step4测试
@RestController
public class MyController {
@Autowired
private SentinelService service;
@GetMapping("/myController")
public String testController() {
return service.success();
}
}
step4:使用jemeter并发测试结果
step5:小心踩坑
Caused by: com.alibaba.csp.sentinel.slots.block.flow.FlowException: null_起球就杀的码农小王的博客-CSDN博客