最新要闻
- 【全球新视野】真的有那么好?试完深蓝SL03我明白了
- 天天观点:四年创收20亿美元!微软XGP PC用户突破1500万
- 大神出手!安卓14/骁龙8 Gen2双双被破解:一键ROOT
- 南非一客机驾驶舱惊现剧毒眼镜蛇往人身上爬 飞行员神勇应对:平安降落
- 全球今日讯!石家庄:医师资格考试报名材料即将发放
- 天天观热点:老司机不刹车?特斯拉潮州事故车主不服鉴定 车顶维权女车主:厂商应公开完整数据
- 世界聚焦:为救高烧幼童 高铁破例停车2分钟
- 【独家】你敢体验吗?菲律宾推出网红蟒蛇按摩服务:40元享受30分钟
- AI抢饭碗成真!近500家企业用ChatGPT取代员工:有公司省超10万美元
- 世界头条:苏炳添回应手机从小米换成苹果:合约已到期 旧手机摔坏了
- 世界热消息:招商银行信用卡网银(中国邮政储蓄余额查询)
- 焦点精选!什么情况?马自达要给CX-50征集中文名:越境、行也、俊驰、览乐你投谁
- 全球即时看!工资六千的岗位面试了6轮!女生发视频吐槽
- 世界观点:TikTok回应英国政府巨额罚款:乐见罚款大幅度降低
- 李国庆称羡慕周鸿祎离婚:没争夺控制权 你就乐吧
- 嫦娥五号采集月壤立功:中国科学家刷新月球死亡时间
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
全球热资讯!SpringBoot中如何编写一个优雅的限流组件?
很早以前,我曾写过两篇介绍如何在SpringBoot中使用Guava和Redis实现接口限流的文章。具体包括:
- 使用Guava实现单机令牌桶限流
- 使用Redis实现分布式限流
现在,一个问题摆在我们面前:如何将这两种限流机制整合到同一个组件中,以便用户随时切换呢?
(资料图片)
显然,我们需要定义一个通用的限流组件,将其引入到业务中,并支持通过配置文件自由切换不同的限流机制。举例而言,当使用limit.type=redis
时,启用Redis分布式限流组件,当使用limit.type=local
时,启用Guava限流组件。这种自由切换机制能够为用户提供更大的灵活性和可维护性。
接下来,让我们开始动手实现吧!
第一步,创建通用模块cloud-limiter-starter
首先在父项目下创建一个模块
然后在pom文件中引入相关依赖
com.google.guava guava org.springframework.boot spring-boot-starter-web provided org.springframework.boot spring-boot-starter-data-redis provided org.projectlombok lombok provided org.springframework spring-aspects provided
小提示:通用模块命名最好遵照规则以starter命名结束,同时通用模块引入的依赖最好设置
属性。
provided
第二步,实现限流功能
- 创建限流接口
既然有两种限流机制,按照套路肯定得先创建一个限流接口,就叫LimiterManager
吧。
public interface LimiterManager { boolean tryAccess(Limiter limiter);}
- 分别实现Redis的限流功能和Guava的限流功能,这里只给出核心代码。
Guava限流的核心实现GuavaLimiter
@Slf4jpublic class GuavaLimiter implements LimiterManager{ private final Map limiterMap = Maps.newConcurrentMap(); @Override public boolean tryAccess(Limiter limiter) { RateLimiter rateLimiter = getRateLimiter(limiter); if (rateLimiter == null) { return false; } boolean access = rateLimiter.tryAcquire(1,100, TimeUnit.MILLISECONDS); log.info("{} access :{}",limiter.getKey() , access); return access; }}
Redis限流的核心实现RedisLimiter
@Slf4jpublic class RedisLimiter implements LimiterManager{ private final StringRedisTemplate stringRedisTemplate; public RedisLimiter(StringRedisTemplate stringRedisTemplate) { this.stringRedisTemplate = stringRedisTemplate; } @Override public boolean tryAccess(Limiter limiter) { String key = limiter.getKey(); if (StringUtils.isEmpty(key)) { throw new LimiterException( "redis limiter key cannot be null" ); } List keys = new ArrayList<>(); keys.add( key ); int seconds = limiter.getSeconds(); int limitCount = limiter.getLimitNum(); String luaScript = buildLuaScript(); RedisScript redisScript = new DefaultRedisScript<>(luaScript, Long.class); Long count = stringRedisTemplate.execute( redisScript, keys, "" + limitCount, "" + seconds ); log.info( "Access try count is {} for key={}", count, key ); return count != null && count != 0; }}
第三步,创建配置类
编写配置类根据配置文件注入限流实现类,当配置文件中属性 limit.type=local
时启用Guava限流机制,当limit.type=redis
时启用Redis限流机制。
@Configurationpublic class LimiterConfigure { @Bean @ConditionalOnProperty(name = "limit.type",havingValue = "local") public LimiterManager guavaLimiter(){ return new GuavaLimiter(); } @Bean @ConditionalOnProperty(name = "limit.type",havingValue = "redis") public LimiterManager redisLimiter(StringRedisTemplate stringRedisTemplate){ return new RedisLimiter(stringRedisTemplate); }}
第四步,创建AOP
根据前面的两篇文章可知,避免限流功能污染业务逻辑的最好方式是借助Spring AOP,所以很显然还得需要创建一个AOP。
@Aspect@EnableAspectJAutoProxy(proxyTargetClass = true) //使用CGLIB代理@Conditional(LimitAspectCondition.class)public class LimitAspect { @Setter(onMethod_ = @Autowired) private LimiterManager limiterManager; @Pointcut("@annotation(com.jianzh5.limit.aop.Limit)") private void check() { } @Before("check()") public void before(JoinPoint joinPoint){ MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); Limit limit = method.getAnnotation(Limit.class); if(limit != null){ Limiter limiter = Limiter.builder().limitNum(limit.limitNum()) .seconds(limit.seconds()) .key(limit.key()).build(); if(!limiterManager.tryAccess(limiter)){ throw new LimiterException( "There are currently many people , please try again later!" ); } } }}
注意到类上我加了一行@Conditional(LimitAspectCondition.class)
,使用了自定义条件选择器,意思是只有当配置类中出现了limit.type
属性时才会加载这个AOP。
public class LimitAspectCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { //检查配置文件是否包含limit.type属性 return conditionContext.getEnvironment().containsProperty(ConfigConstant.LIMIT_TYPE); }}
第四步,创建spring.factories文件,引导SpringBoot加载配置类
## AutoConfigurationorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.jianzh5.limit.config.LimiterConfigure,\ com.jianzh5.limit.aop.LimitAspect
完整目录结构如下:
第五步,在项目中引用限流组件
- 引入依赖
com.jianzh5 cloud-limit-starter
- 在application.properties中设置加载的限流组件
limit.type = redis
如果不配置此属性则不加载对应限流功能。
- 在需要限流的接口上加上注解
@Limit(key = "Limiter:test",limitNum = 3,seconds = 1)
小结
通过上述步骤,我们已经成功实现了一个通用限流组件。在实际应用中,只需要根据场景需求选择对应的限流机制,即可非常方便的进行限流操作。这种灵活性和便捷性,也是SpringBoot中定义Starter的一般套路。
如果你想详细了解这两种限流机制的原理,可以参考之前的文章中所介绍的内容。
老鸟系列源码已经上传至GitHub,需要的在公号【JAVA日知录】回复关键字 0923获取源码地址。
关键词:
全球热资讯!SpringBoot中如何编写一个优雅的限流组件?
环球今热点:一文快速了解火山引擎 A/B 测试平台
小程序对接三方插件契约锁
【全球新视野】真的有那么好?试完深蓝SL03我明白了
诺基亚E72i手机什么时候上市的?诺基亚E72i手机参数
摩尔庄园怎么获得桑叶?摩尔庄园怎么收获农作物?
龙之谷白屏是怎么回事?龙之谷白屏怎么解决?
天天观点:四年创收20亿美元!微软XGP PC用户突破1500万
大神出手!安卓14/骁龙8 Gen2双双被破解:一键ROOT
南非一客机驾驶舱惊现剧毒眼镜蛇往人身上爬 飞行员神勇应对:平安降落
闲鱼曝光率突然下降怎么办?闲鱼曝光率怎么提高?
闲鱼对方被处置能回复消息吗?闲鱼对方被处置能正常发货吗?
全球热文:某公司技术经理媚上欺下,打工人应怼尽怼,嘤其鸣兮,求其友声!
焦点讯息:用上这几种.NET EF Core性能调优,查询性能飙升
全球今日讯!石家庄:医师资格考试报名材料即将发放
天天观热点:老司机不刹车?特斯拉潮州事故车主不服鉴定 车顶维权女车主:厂商应公开完整数据
世界聚焦:为救高烧幼童 高铁破例停车2分钟
【独家】你敢体验吗?菲律宾推出网红蟒蛇按摩服务:40元享受30分钟
AI抢饭碗成真!近500家企业用ChatGPT取代员工:有公司省超10万美元
世界头条:苏炳添回应手机从小米换成苹果:合约已到期 旧手机摔坏了
【世界快播报】K8S学习圣经6:资源控制+SpringCloud动态扩容原理和实操
环球热议:顶象受邀加入“数字政府网络安全产业联盟”
Blender插件:Muscle System
天天短讯!两单REIT业绩说明会首次在上海证券交易所成功举办
世界热消息:招商银行信用卡网银(中国邮政储蓄余额查询)
焦点精选!什么情况?马自达要给CX-50征集中文名:越境、行也、俊驰、览乐你投谁
全球即时看!工资六千的岗位面试了6轮!女生发视频吐槽
世界观点:TikTok回应英国政府巨额罚款:乐见罚款大幅度降低
李国庆称羡慕周鸿祎离婚:没争夺控制权 你就乐吧
嫦娥五号采集月壤立功:中国科学家刷新月球死亡时间
环球资讯:EasyMR 安全架构揭秘:如何管理 Hadoop 数据安全
小程序容器助力组装移动银行超级APP
【环球报资讯】GPS北斗卫星时钟服务器在飞机场内网中的应用
和讯个股快报:2023年04月06日 紫天科技(300280),该股K线呈现“乌云盖顶”形态
头条:24小时长效锁水 妮维雅男士精华露39.9元狂促:送洁面乳50gx2
车市“价格战”开打一月:新车销量未回暖 二手准新车被坑惨
速递!杨元庆:联想过去三年营收增长1100亿 PC业务还是第一
焦点快报!游客开车陷进沙滩:拖车开口要价5千 待会涨潮至少要5万
环球动态:最快6月2日早就能玩到!《暗黑4》全球解锁时间公开
世界视点!清明时节祭祖扫墓 “小三通”客运航线往来忙碌
每日短讯:全网最详细中英文ChatGPT-GPT-4示例文档-会议笔记文档智能转摘要从0到1快速入门——官网推荐的48种最佳应用场景(附python/node.
世界即时:Linux在游戏界的口碑树立
前端设计模式——MVC模式
福岛核电站1号机组底座受损严重!日本民众集会反对核污水排海
环球新消息丨特斯拉发布“宏图计划3”完整文件 10万亿美元改变地球
形似“摄魂怪” 澳大利亚悉尼惊现破片云:颜色漆黑、预示狂风暴雨
全球今热点:Redmi Note 12 Turbo好评率99%!卢伟冰:得到极大认可 把竞品甩在后面
快看点丨划时代产品!特斯拉新款小型电动汽车公布 目标销量4200万辆
世界速读:我2022年8月18月去医院做牙齿矫正,但是我只交了定金,后续也没拿到牙套
SpringBoot如何进行限流,老鸟们还可以这样玩!
环球微资讯!Podman Compose 新手指南
环球今热点:美国ADP就业数据不及预期 暗示劳动力需求降温
焦点快报!深赛格:融资净买入132.4万元,融资余额1.03亿元(04-04)
天天报道:中国为何未研制出ChatGPT?中科院包云岗:需要优秀技术团队、雄厚资金
苏炳添用iPhone 14引热议 本人回应:与小米合约到期 手机摔坏才换
大妈捡手机要好处费2包烟见面变500元被吐槽:你捡到会痛快归还吗?
焦点速读:NV不愁卖!2023年PC游戏硬件市场继续萎缩:AMD、Intel显卡要打对折卖
每日资讯:沪广深去年公积金个贷降两成 今年超60地优化公积金政策
天天速递!科技伦理审查提速 AI“变坏”设防
天天最资讯丨核污水将倒入大海 降低水产品辐射分析精度!日本1.8亿粒扇贝不明原因死亡
世界快看:64位才是王道!《英雄联盟》13.7版本今日更新:32位Win系统续一条命
汽车仪表盘显示感叹号加个圆圈_汽车仪表盘显示感叹号
【天天报资讯】读SQL进阶教程笔记10_HAVING下
Python 开发环境安装
世界热文:海盗船192GB DDR5内存套装开卖:带上“光污染” 7699元!
天天百事通!研究了2600多篇爆仓文学后 我好像搞懂人是怎么变赌狗的了
天天看点:无数人的童年回忆:重制后把我裤子都感动湿了
标准版也要有高刷了!iPhone全系列或于2025年引入LTPO技术
【环球时快讯】穿越之汉武帝
世界微速讯:彻底崩了!AI遭全球“围剿” A股咋应对?超9000人联名“封杀” 巴菲特又要“抄底”?
【打怪升级】【jvm】关于jvm内存模型及GC调优
【当前热闻】房东称闰二月要多交1个月房租 网友:这是住在月亮上吗?
ChatGPT需要1万张NVIDIA A100显卡 国内仅有6家公司做到
全球快消息!杭州一男子坐地铁自带沙发 怎么过的安检?地铁回应
焦点热讯:Lambda
TVM Deploy Runtime[施工中]
环球精选!股债二八平衡策略
世界实时:20年来最优秀游戏处理器!AMD锐龙7 7800X3D首发评测:大幅超越i9-13900KS
周鸿祎离婚给前妻90亿 李国庆羡慕:没争夺控制权 他就乐吧
RTX 3060登顶Steam神卡 AMD显卡被黑?竟是国内玩家的锅
全球快资讯丨“索要千万逼死老公案”五年后一审宣判:妻子翟欣欣退还男方上千万财产
环球热头条丨我的第一个项目(九) :飞机大战Vue版本塞到主页
Unity开发Hololens2—环境配置
设计模式(三十二)----综合应用-自定义Spring框架-自定义Spring IOC-自定义Spring IOC总结
CS50-Python实验3,4
天天精选!00后都开始立遗嘱了:微信号、QQ号、游戏账号成热门虚拟财产
《他是谁》烂尾 编剧疑似甩锅剧本总监:感谢你把剧本改成这
世界快讯:莱万:若留拜仁或会失去踢球的乐趣 在巴萨除了进球我有不同角色
【全球热闻】上映25周年纪念!《泰坦尼克号》4K重映版票房破2000万
每日热点:全球首例真人状告机器人!澳大利亚一市长准备告ChatGPT诽谤
Cesium 案例(二)Web MapTile Service with Time
渗透测试——简单的流程化信息收集
胖东来创始人称加班不道德:不能只挣钱
世界热头条丨在Steam上买了个假冒黄游 结果居然给我玩爽了
焦点热文:女子称使用化妆品后流产 送检发现:汞含量超标30万倍!
每日消息!俄罗斯一男子19楼坠落后自行上救护车:还给医务人员唱了歌
全球热文:速速电影院-尽情泡约网电影院
索尼推出WF-C700N无线耳机:15小时长续航、支持空间音频
GT2大探成最后一款!真我手机将不再有“大师探索版”
福布斯发布2023亿万富豪榜:亚马逊贝索斯最惨 资产流失近4000亿