SpringBoot(三十六)SpringBoot使用sentinel自定义注解实现限流

devtools/2024/11/26 7:36:07/

前边我们学习了阿里的限流工具sentinel。她是有一个@SentinelResource注解可以使用的,但是呢,使用@SentinelResource注解需要链接sentinel控制台,在控制台中创建对应的规则。

再在对应的方法中使用@SentinelResource注解来配置功能。

但是呢,我这里有一个小小的尴尬,我目前使用的是springboot项目,而非springCloud,也可能是我配置的问题,连接sentinel控制台始终没有成功。

所以我就没有办法使用@SentinelResource注解了,但是我还不想使用其他方式来对方法进行限流,那怎么办呢?

很简单,我们之前学过自定义注解这个东西啊。

一:定义一个注解

java">package com.modules.customannotations.myAnnotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MySentinelResource
{// 可以定义一些属性,如果不需要,可以留空String resource();int number() default 1;// 这个可以不传参数
}

二:定义注解对应的切面类

java">package com.modules.customannotations.annotationAspect;import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.modules.customannotations.myAnnotation.MySentinelResource;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.List;@Aspect   // 声明该类为一个注解类;
@Component
public class MySentinelResourceAspect
{private final static Logger logger = LoggerFactory.getLogger(MyCustomAnnotationAspect.MyCustomAspect.class);// 自定义注解参数/*** 资源名称*/private String resource;/*** 限流数量*/private int number;// 以自定义 @MySentinelResource 注解为切点 --- @annotation里配置的 @MySentinelResource的自定义注解的全路径名@Pointcut("@annotation(com.modules.customannotations.myAnnotation.MySentinelResource)")public void mySentinelResourcePointcut() {}/*** 在切点之前,织入相关代码;* @param joinPoint* @param mySentinelResource*/@Before("@annotation(mySentinelResource)")public void beforeMethod(JoinPoint joinPoint, MySentinelResource mySentinelResource) throws Exception{Entry ignored = null;try{// 获取注解的参数this.resource = mySentinelResource.resource();this.number = mySentinelResource.number();/* 1.创建存放限流规则的集合 */List<FlowRule> rules = new ArrayList<>();/* 2.创建限流规则 */FlowRule rule = new FlowRule();/* 定义资源,表示 Sentinel 会对哪个资源生效 "AddUser" */rule.setResource(resource);/* 定义限流的类型(此处使用 QPS 作为限流类型) */rule.setGrade(RuleConstant.FLOW_GRADE_QPS);/* 定义 QPS 每秒通过的请求数 1 */rule.setCount(number);/* 3.将限流规则存放到集合中 */rules.add(rule);/* 4.加载限流规则 */FlowRuleManager.loadRules(rules);// 设置一个资源名称为 Helloignored = SphU.entry(resource);}catch(Exception e){ // 被限流之后就会进入到这里来// 方法执行前的逻辑,终止程序执行可以通过抛出异常或其他方式实现throw new RuntimeException("别急,等一会在请求!");}finally{ // 兜底方法,销毁资源// 销毁资源if (ignored != null){ignored.exit();}}}/*** 环绕,可以在切入点前后织入代码,并且可以自由的控制何时执行切点;* @param point* @return* @throws Throwable*/@Around("mySentinelResourcePointcut()")private Object testAop(ProceedingJoinPoint point) throws Throwable{// 获取方法返回的数据Object obj = point.proceed();//System.out.println("obj:"+obj);return obj;}
}

这里我在做的时候钻牛角尖了,我在@Before注解定义的方法中对资源进行限流,但是呢,有一个小问题,这个方法是没有返回值的,也不能终止程序,这可怎么办呢?

后来我一寻思,这不傻了吗,我可以抛出异常啊,抛出异常程序不就停止了吗。

在结合我前边定义的全局异常处理类,直接这不就圆满了吗。

调用:

java">@MySentinelResource(resource = "getData", number = 1) // 自定义注解:sentinel限流
public Map<String, Object> getData(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "") String search)
{Map<String, Object> result = indexService.getData(page, search);
}

到这里,使用sentinel自定义注解对请求限流就完成了。

有好的建议,请在下方输入你的评论。


http://www.ppmy.cn/devtools/137058.html

相关文章

python操作Elasticsearch

使用elasticsearch 6.x版本&#xff0c;操作es数据。 #! -*- coding:utf-8 -* import timefrom elasticsearch import Elasticsearch, helpersclass EstUtil:_instance Nonedef __new__(cls, *args, **kwargs):if not cls._instance:cls._instance super(EstUtil, cls).__ne…

【论文笔记】Number it: Temporal Grounding Videos like Flipping Manga

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Number it: Temporal Grou…

STM32H7开发笔记(2)——H7外设之多路定时器中断

STM32H7开发笔记&#xff08;2&#xff09;——H7外设之多路定时器中断 文章目录 STM32H7开发笔记&#xff08;2&#xff09;——H7外设之多路定时器中断0.引言1.CubeMX配置2.软件编写 0.引言 本文PC端采用Win11STM32CubeMX4.1.0.0Keil5.24.2的配置&#xff0c;硬件使用STM32H…

java charAt()返回数值型 详解

Java 中 charAt() 返回数值型详解 在 Java 中&#xff0c;charAt() 方法返回的是 char 类型&#xff0c;它代表的是字符&#xff0c;但字符在计算机中也有对应的数值表示&#xff08;ASCII 或 Unicode 编码&#xff09;。通过将 char 类型转换或直接参与计算&#xff0c;我们可…

emacs入门命令、android-studio和Android Gradle plugin(AGP)版本对照、zulu网页查找jdk11最新版下载脚本

emacs入门命令 ubuntu 22.04下emacs基本操作 sudo apt install -y emacs 图形化emacs | 文本化emacs --no-window-system, 快捷键Altx(M x)执行命令: shell #打开交互式shell终端 #emacs控制shell更精确 term #打开交互式终端(默认/bin/bash) #emacs几乎不能控制…

智控水利:道品科技农业灌区自动化闸门引领农业灌溉新变革

一、引言 农业灌溉作为农业生产的关键环节&#xff0c;直接影响着农作物的生长、产量与质量。在传统农业灌区中&#xff0c;闸门的操作主要依赖人工&#xff0c;这种方式在当今科技飞速发展的时代背景下&#xff0c;暴露出诸多弊端。道品科技农业灌区自动化闸门的出现&#xff…

GoZero对接GPT接口的设计与实现:问题分析与解决

在本篇文章中&#xff0c;我们将探讨如何在GoZero框架下对接GPT接口&#xff0c;并详细讨论在实现过程中遇到的一些常见问题及其解决方案。特别是遇到的错误信息&#xff0c;如 parse parameter fail,recover: interface conversion: interface {} is nil, not string 和 获取历…

网络基础 - 地址篇

一、IP 地址 IP 协议有两个版本&#xff0c;IPv4 和 IPv6IP 地址(IPv4 地址)是一个 4 字节&#xff0c;32 位的正整数&#xff0c;通常使用 “点分十进制” 的字符串进行表示&#xff0c;例如 192.168.0.1&#xff0c;用点分割的每一个数字表示一个字节&#xff0c;范围是 0 ~…