Sentinel: 使用注解限流
在前面我们对Sentinel做了一个详细的介绍,可以手动的通过Sentinel提供的SphU类来保护资源。这种做法不好的地方在于每个需要限制的地方都得写代码,从 0.1.1 版本开始,Sentinel 提供了 @SentinelResource 注解的方式,非常方便。
要使用注解来保护资源需要引入下面的Maven依赖:
<dependency>
	<groupId>com.alibaba.csp</groupId>
	<artifactId>sentinel-annotation-aspectj</artifactId>
	<version>1.4.1</version>
</dependency>
引入之后我们需要配置SentinelResourceAspect切面让其生效,因为是通过SentinelResourceAspect切面来实现的,我这边以Spring Boot中使用进行配置示列:
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注解即可:
@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 函数,否则无法解析。
业务方法:
@SentinelResource(value = "get2", blockHandler = "handleException", blockHandlerClass = { ExceptionUtil.class })
@Override
public String get2() {
	return "http://cxytiandi.com";
}
异常处理类:
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等。
@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的源码
@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限流示例:编码和注解限流
		一.Sentinel 是什么? 随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性. Sentine ... 
- Spring Cloud Alibaba基础教程:使用Sentinel实现接口限流
		最近管点闲事浪费了不少时间,感谢网友libinwalan的留言提醒.及时纠正路线,继续跟大家一起学习Spring Cloud Alibaba. Nacos作为注册中心和配置中心的基础教程,到这里先告一 ... 
- Spring Cloud Alibaba 使用Sentinel实现接口限流
		Sentinel是什么 Sentinel的官方标题是:分布式系统的流量防卫兵.从名字上来看,很容易就能猜到它是用来作服务稳定性保障的.对于服务稳定性保障组件,如果熟悉Spring Cloud的用户,第 ... 
- 快速体验 Sentinel 集群限流功能,只需简单几步
		️ Pic by Alibaba Tech on Facebook 集群限流 可以限制某个资源调用在集群内的总 QPS,并且可以解决单机流量不均导致总的流控效果不佳的问题,是保障服务稳定性的利器. S ... 
- Sentinel整合Dubbo限流实战(分布式限流)
		之前我们了解了 Sentinel 集成 SpringBoot实现限流,也探讨了Sentinel的限流基本原理,那么接下去我们来学习一下Sentinel整合Dubbo及 Nacos 实现动态数据源的限流 ... 
- springBoot整合Sentinel实现降级限流熔断
		由于hystrix的停止更新,以及阿里Sentinel在历年双十一的贡献.项目中使用了Sentinel,今天我们来讲讲Sentinel的入门教程,本文使用1.6.3版本进行讲解 本文通过Sentine ... 
- 微服务架构 | 5.2 基于 Sentinel 的服务限流及熔断
		目录 前言 1. Sentinel 基础知识 1.1 Sentinel 的特性 1.2 Sentinel 的组成 1.3 Sentinel 控制台上的 9 个功能 1.4 Sentinel 工作原理 ... 
- Spring Cloud alibaba网关 sentinel zuul 四 限流熔断
		spring cloud alibaba 集成了 他内部开源的 Sentinel 熔断限流框架 Sentinel 介绍 官方网址 随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentine ... 
- Spring Cloud Alibaba系列(五)sentinel实现服务限流降级
		一.sentinel是什么 sentinel的官方名称叫分布式系统的流量防卫兵.Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性.在Spring Clou ... 
随机推荐
- 十、Spring之BeanFactory源码分析(二)
			Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ... 
- Java-100天知识进阶-JVM内存-知识铺(三)
			知识铺: 致力于打造轻知识点,持续更新每次的知识点较少,阅读不累.不占太多时间,不停的来唤醒你记忆深处的知识点. Java内存模型(JMM) JVM内存模式是JVM的内存分区 Java内存模式是一种虚 ... 
- CompletableFuture3
			public class CompletableFuture3 { public static void main(String[] args) throws ExecutionException, ... 
- C# 5.0 新特性之异步方法(AM)
			Ø 前言 C# Asynchronous Programming(异步编程)有几种实现方式,其中 Asynchronous Method(异步方法)就是其中的一种.异步方法是 C#5.0 才有的新特 ... 
- Kubernetes DaemonSet(部署守护进程)
			Kubernetes DaemonSet(部署守护进程) • 在每一个Node上运行一个Pod• 新加入的Node也同样会自动运行一个Pod 应用场景:Agent 官方文档:https://kuber ... 
- VMware+windbg时快照功能的使用
			VMware+windbg时快照功能的使用 一.快照功能的使用 我们在编写与调试驱动文件时经常会面临死机蓝屏情况,如果像平常一样重启,再重新配置环境,肯定会占用大量时间. Vmware虚拟机给我们提供 ... 
- WPF xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
			<Button Grid.Row="1" Content="Load Data" BorderBrush="Black" Border ... 
- Python如何实现单例模式?其他23中设计模式python如何实现?
			单例模式主要有四种方法:new.共享属性.装饰器.import. # __ new__方法: class Singleton(object): def __new__(cls, *args, **kw ... 
- Locust 接口性能测试 - 转载一  (后期熟悉实践自己出一套完整的)
			转载大佬 ,.. 另外一篇:https://www.cnblogs.com/imyalost/p/9758189.html记录一下接口性能测试的学习 先熟悉一下概念: Locust是使用Pytho ... 
- 初识Android App自动化测试框架--Unittest
			1.为什么需要使用框架实现自动化测试 作为测试工程师,可能在代码能力上相比开发工程师要弱一点,所以我们在写脚本的时候就会相对容易的碰到更多的问题,如果有一个成熟的框架供给我们使用的话,可以帮助我们避免 ... 
