前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >利用AOP手写一个简单的熔断和限流

利用AOP手写一个简单的熔断和限流

作者头像
用户1215919
发布于 2021-12-28 04:42:50
发布于 2021-12-28 04:42:50
43100
代码可运行
举报
文章被收录于专栏:大大的微笑大大的微笑
运行总次数:0
代码可运行

MAVEN依赖

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- aspectj -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.2</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.2</version>
        </dependency>

注解类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RateLimiter {

    int timeout() default -1;
	int count() default -1;
}

AOP处理类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component
@Aspect
public class RatelimiterAop {
	  private static ConcurrentHashMap<String, Semaphore> LIMITER = new ConcurrentHashMap<>();
    @Pointcut("@annotation(RateLimiter)")
    public void point() {

    }

    @Around("point()")
    public Object limit(ProceedingJoinPoint proceedingJoinPoint) {
        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
        RateLimiter limit = methodSignature.getMethod().getDeclaredAnnotation(RateLimiter.class);
        if (limit.timeout() > 0) {
            ExecutorService es = Executors.newFixedThreadPool(2);
            Future future = es.submit(() -> {
                try {
                    return proceedingJoinPoint.proceed();
                } catch (Throwable throwable) {
                    return null;
                }
            });
            final Object obj;
            try {
                obj = future.get(limit.timeout(), TimeUnit.MILLISECONDS);
                return obj;
            } catch (Exception e) {
                future.cancel(true);
                throw new RuntimeException("处理超时");
            }

        }else if (limit.count() > 0) {
            // key unique.
            String cacheKey = proceedingJoinPoint.getTarget().getClass().getName() + "::" + methodSignature.getName()
                    + "::" + Arrays.toString(methodSignature.getParameterNames());
            LIMITER.putIfAbsent(cacheKey, new Semaphore(limit.count()));
            System.out.println(cacheKey);

            Semaphore semaphore = LIMITER.get(cacheKey);
            try {
                semaphore.acquire();
                proceedingJoinPoint.proceed();
            } catch (Throwable throwable) {
               throw  new RuntimeException("请求异常");
            } finally {
                // 释放
                if (null != semaphore) {
                    semaphore.release();
                }
            }

        }


        try {
            return proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            return null;
        }
    }

测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RestController
public class TestController {
    @RateLimiter(timeout = 100)
    @PostMapping(value = "/test")
    public void test(){
        try {
            Random random = new Random();
            int time = random.nextInt(200);
            System.out.println(time + "ms");
            Thread.sleep(time);
            System.out.println("the end");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【高并发】亿级流量场景下如何为HTTP接口限流?看完我懂了!!
作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:
冰河
2020/10/29
8270
【高并发】亿级流量场景下如何为HTTP接口限流?看完我懂了!!
SpringBoot利用限速器RateLimiter实现单机限流
一. 概述 参考开源项目https://github.com/xkcoding/spring-boot-demo 在系统运维中, 有时候为了避免用户的恶意刷接口, 会加入一定规则的限流, 本Demo使用速率限制器com.xkcoding.ratelimit.guava.annotation.RateLimiter实现单机版的限流 二. SpringBootDemo 2.1 依赖 <dependency> <groupId>org.springframework.boot</grou
用户7741497
2022/03/24
1.4K0
一起来学SpringBoot | 第二十七篇:优雅解决分布式限流
在前面的两篇文章中,介绍了一些限流的类型和策略,本篇从 SpringBoot、 Redis 应用层面来实现分布式的限流....
battcn
2018/08/14
3.3K0
一起来学SpringBoot | 第二十七篇:优雅解决分布式限流
SpringBoot 服务接口限流方案
在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。限流可以认为服务降级的一种,限流通过限制请求的流量以达到保护系统的目的。
Jensen_97
2023/07/20
1.2K0
SpringBoot 服务接口限流方案
Spring AOP及事务配置三种模式详解
Spring AOP的设计思想,就是通过动态代理,在运行期对需要使用的业务逻辑方法进行增强。
用户4268038
2021/11/18
3160
SpringBoot - 优雅的实现【流控】
限流 简言之就是当请求达到一定的并发数或速率,就对服务进行等待、排队、降级、拒绝服务等操作。
小小工匠
2022/03/01
1.5K0
SpringBoot - 优雅的实现【流控】
自定义注解限流
注解用来给类声明附加额外信息,可以标注在类、字段、方法等上面,编译器、JVM以及开发人员等都可以通过反射拿到注解信息,进而做一些相关处理
高大北
2022/06/14
2240
基于Reids与AOP实现的定时任务锁-ScheduledLock
简单来说就是通过aop环绕切片将需要加锁的方法包起来,然后在执行前往redis中用setIfAbsent写入一个key,如果返回true,说明没有其他服务正在执行该方法,就继续执行,如果返回false,说明已经有其他服务正在执行该方法,就不执行。
Diuut
2022/11/22
6790
spring aop的五大通知类
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/106636.html原文链接:https://javaforall.cn
全栈程序员站长
2022/08/04
6550
spring aop的五大通知类
基于redis实现注解接口限流
至于市面上流行的限流算法和实现方式,此处不再展开介绍,我们主要针对业务接口维度的限流做分析。
叔牙
2023/02/26
1K0
基于redis实现注解接口限流
面向切面编程
面向切面编程(Aspect Oriented Programming),简称AOP。作为面向对象编程的一个强力补充,在业务系统中很少被关注,却随着Spring的出现而名声鹊起。
李鸿坤
2020/07/18
1.1K0
面向切面编程
Guava RateLimiter 实现 API 限流,这才是正确的姿势!
Guava提供的RateLimiter可以限制物理或逻辑资源的被访问速率,咋一听有点像java并发包下的Samephore,但是又不相同,RateLimiter控制的是速率,Samephore控制的是并发量。
JAVA葵花宝典
2021/10/20
10K0
分布式限流之Redis+Lua实现
【转载请注明出处】:https://cloud.tencent.com/developer/article/1623236
后端老鸟
2020/05/04
6720
分布式限流之Redis+Lua实现
JAVA高并发 Redis+Lua限流实战
但是我们也知道,限流器在每次请求令牌和放入令牌操作中,存在一个协同的问题,即获取令牌操作要尽可能保证原子性,否则无法保证限流器是否能正常工作。在RateLimiter的实现中使用了mutex作为互斥锁来保证操作的原子性,那么在redis中就需要一个类似于事务的机制来保证获取令牌中多重操作的原子性。 面对这样的需求,我们有几个选择:
小东啊
2019/06/26
3.4K0
JAVA高并发 Redis+Lua限流实战
spring的aop注解(java自定义注解)
该篇以记录接口调用的传入参数日志为场景,来介绍下使用自定义注解作为切点,AOP切面方式去记录每个接口的传入参数以及可扩展的业务处理。
全栈程序员站长
2022/07/29
7730
spring的aop注解(java自定义注解)
SpringBoot 通过自定义注解实现AOP切面编程实例
一直心心念的想写一篇关于AOP切面实例的博文,拖更了许久之后,今天终于着手下笔将其完成。
翎野君
2023/05/12
1.1K0
SpringBoot 通过自定义注解实现AOP切面编程实例
艾编教学笔记:高并发限流+分布式限流高并发限流技术揭秘
在分布式领域,我们难免会遇到并发量突增,对后端服务造成高压力,严重甚至会导致系统宕机。为避 免这种问题,我们通常会为接口添加限流、降级、熔断等能力,从而使接口更为健壮。Java领域常见的 开源组件有Netflix的hystrix,阿里系开源的sentinel等,都是蛮不错的限流熔断框架。
艾编程
2020/06/12
1.6K0
艾编教学笔记:高并发限流+分布式限流高并发限流技术揭秘
Spring基础(十一):AOP注解和XML方式实现
注意:AspectJ本身并不是spring框架中的组成部分, 是一个独立的AOP框架,一般把AspectJ和Spring框架的AOP依赖一起使用,所以要导入一个独立的依赖
Lansonli
2022/12/26
5370
Spring基础(十一):AOP注解和XML方式实现
Spring AOP入门使用详解
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/149583.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/05
2280
如何实现一个SpringBoot Starter
Starter是SpringBoot中的一个非常重要的概念,Starter相当于模块,它能将模块所需的依赖整合起来并对模块内的Bean根据条件进行自动配置。 使用者只需要依赖相应功能的Starter,无需做过多的配置和依赖,SpringBoot就能自动扫描并加载相应的模块。 例如我们在创建SpringBoot项目时,经常会引入如spring-boot-starter-web这种依赖,该依赖为我们做了很多默认配置, 无需再依赖spring-web、spring-webmvc等相关包及做相关配置就能够立即使用它。
wo.
2021/06/15
5740
如何实现一个SpringBoot Starter
相关推荐
【高并发】亿级流量场景下如何为HTTP接口限流?看完我懂了!!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文