我是靠谱客的博主 无限仙人掌,这篇文章主要介绍Sentinel: 使用注解限流,现在分享给大家,希望可以做个参考。

在前面我们对Sentinel做了一个详细的介绍,可以手动的通过Sentinel提供的SphU类来保护资源。这种做法不好的地方在于每个需要限制的地方都得写代码,从 0.1.1 版本开始,Sentinel 提供了 @SentinelResource 注解的方式,非常方便。

要使用注解来保护资源需要引入下面的Maven依赖:

复制代码
1
2
3
4
5
6
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-annotation-aspectj</artifactId> <version>1.4.1</version> </dependency> 复制代码

引入之后我们需要配置SentinelResourceAspect切面让其生效,因为是通过SentinelResourceAspect切面来实现的,我这边以Spring Boot中使用进行配置示列:

复制代码
1
2
3
4
5
6
7
8
9
10
11
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect; @Configuration public class AopConfiguration { @Bean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); } } 复制代码

然后在需要限制的方法上加SentinelResource注解即可:

复制代码
1
2
3
4
5
6
7
8
9
10
@SentinelResource(value = "get", blockHandler = "exceptionHandler") @Override public String get(String id) { return "http://cxytiandi.com"; } public String exceptionHandler(String id, BlockException e) { e.printStackTrace(); return "错误发生在" + id; } 复制代码

SentinelResource:value

表示资源名,必填项

SentinelResource:blockHandler

处理 BlockException 的方法名,可选项。若未配置,则将 BlockException 直接抛出。

  • blockHandler 函数访问范围需要是 public
  • 返回类型需要与原方法相匹配
  • 参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException
  • blockHandler 函数默认需要和原方法在同一个类中

如果你不想让异常处理方法跟业务方法在同一个类中,可以使用 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

业务方法:

复制代码
1
2
3
4
5
6
@SentinelResource(value = "get2", blockHandler = "handleException", blockHandlerClass = { ExceptionUtil.class }) @Override public String get2() { return "http://cxytiandi.com"; } 复制代码

异常处理类:

复制代码
1
2
3
4
5
6
7
8
import com.alibaba.csp.sentinel.slots.block.BlockException; public final class ExceptionUtil { public static String handleException(BlockException ex) { System.err.println("错误发生: " + ex.getClass().getCanonicalName()); return "error"; } } 复制代码

如何测试?

我们可以在Spring Boot的启动类中定义规则,然后快速访问接口,就可以看出效果啦,或者用压力测试工具ab等。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@SpringBootApplication public class App { public static void main(String[] args) { initFlowRules(); SpringApplication.run(App.class, args); } private static void initFlowRules() { List<FlowRule> rules = new ArrayList<>(); FlowRule rule = new FlowRule(); rule.setResource("get"); rule.setGrade(RuleConstant.FLOW_GRADE_QPS); rule.setCount(1); rules.add(rule); rule = new FlowRule(); rule.setResource("get2"); rule.setGrade(RuleConstant.FLOW_GRADE_QPS); rule.setCount(1); rules.add(rule); FlowRuleManager.loadRules(rules); } } 复制代码

源码分析

只需要配置了SentinelResourceAspect就可以使用注解,我们来简单的看下SentinelResourceAspect的源码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Aspect public class SentinelResourceAspect extends AbstractSentinelAspectSupport { @Pointcut("@annotation(com.alibaba.csp.sentinel.annotation.SentinelResource)") public void sentinelResourceAnnotationPointcut() { } @Around("sentinelResourceAnnotationPointcut()") public Object invokeResourceWithSentinel(ProceedingJoinPoint pjp) throws Throwable { // 获取当前访问的方法 Method originMethod = resolveMethod(pjp); // 获取方法上的SentinelResource注解 SentinelResource annotation = originMethod.getAnnotation(SentinelResource.class); if (annotation == null) { // Should not go through here. throw new IllegalStateException("Wrong state for SentinelResource annotation"); } // 获取资源名 String resourceName = getResourceName(annotation.value(), originMethod); EntryType entryType = annotation.entryType(); Entry entry = null; try { entry = SphU.entry(resourceName, entryType, 1, pjp.getArgs()); Object result = pjp.proceed(); return result; } catch (BlockException ex) { // 处理被限制的异常,回调事先配置的异常处理方法 return handleBlockException(pjp, annotation, ex); } catch (Throwable ex) { Tracer.trace(ex); throw ex; } finally { if (entry != null) { entry.exit(); } } } } 复制代码

上面是整个切面的代码,对所有加了SentinelResource注解的方法进去切入。细节代码在AbstractSentinelAspectSupport中,大家自己去看看。

欢迎加入我的知识星球,一起交流技术,免费学习猿天地的课程(http://cxytiandi.com/course)

PS:目前星球中正在星主的带领下组队学习Sentinel,等你哦!

最后

以上就是无限仙人掌最近收集整理的关于Sentinel: 使用注解限流的全部内容,更多相关Sentinel:内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(78)

评论列表共有 0 条评论

立即
投稿
返回
顶部