接口也会累着!SpringBootRedis实现接口限流和防刷
越来越多的应用被部署到了云端,并在云端被高并发的访问。在这样的环境下,限流和防刷是非常重要的,因为如果不做好限流和防刷,那么很容易就会因为访问量过大而导致应用崩溃。在本文中,我们将会介绍如何使用Spring Boot和Redis来实现访问限流和接口防刷。篇幅有点长,但是满满的干活,大家地铁上慢慢看!!!什么是限流和防刷?
在介绍如何使用Spring Boot和Redis实现限流和防刷之前,我们先来了解一下什么是限流和防刷。
限流,顾名思义,就是限制流量,也就是限制同一时间内能够访问某个接口的请求数量。通过限流,我们可以保证系统的稳定性,避免因为访问量过大而导致系统宕机的情况发生。
防刷,是指防止恶意请求,比如恶意爬虫、恶意攻击等。如果系统没有做好防刷,那么恶意请求很容易就会把系统压垮,因此防刷也是非常重要的一项工作。Spring Boot和Redis
在介绍如何使用Spring Boot和Redis实现限流和防刷之前,我们先来了解一下什么是Spring Boot和Redis。
Spring Boot是一个开源的Java框架,它可以帮助我们快速搭建基于Spring的应用程序,减少了我们的开发时间和成本,同时提高了应用程序的可维护性。
Redis是一个高性能的键值存储系统,它支持多种数据结构,比如字符串、哈希表、列表等等。Redis可以用于缓存、消息队列、计数器等多种用途。实现限流
接下来,我们将会介绍如何使用Spring Boot和Redis来实现限流。
在Redis中,我们可以使用令牌桶算法来实现限流。令牌桶算法的基本思想是,我们有一个固定容量的桶,以固定的速率往里面放入令牌,每当有一个请求需要访问系统时,就需要从桶中取出一个令牌,如果桶中没有令牌了,那么就需要等待,直到桶中有令牌为止。
首先,我们需要在pom.xml中添加以下依赖: org.springframework.boot spring-boot-starter-data-redis
接下来,我们需要在Redis中设置一个哈希表,用来存储每个接口的访问次数和访问时间。其中,哈希表的键是接口的路径,值是一个列表,列表中存储了接口的访问次数和访问时间。我们可以使用以下代码来初始化这个哈希表:@Autowired private RedisTemplate redisTemplate; private static final String LIMIT_KEY_PREFIX = "limit:"; public void initLimitMap(String path, int limitCount, int limitTime) { String key = LIMIT_KEY_PREFIX + path; Map map = new HashMap<>(); map.put("count", 0); map.put("time", limitTime); redisTemplate.opsForHash().putAll(key, map); redisTemplate.expire(key, limitTime, TimeUnit.SECONDS); }
在上面的代码中,我们使用了@Autowired注解来注入RedisTemplate实例。RedisTemplate是Spring提供的一个用于操作Redis的模板类,可以简化我们的Redis操作。
然后,我们可以使用initLimitMap方法来初始化每个接口的访问次数和访问时间。其中,path是接口的路径,limitCount是访问次数的限制,limitTime是访问时间的限制。
接下来,我们需要编写一个拦截器,在每个请求到达接口之前判断是否需要进行限流。在拦截器中,我们需要从Redis中获取当前接口的访问次数和访问时间,然后判断当前时间和上次访问时间的时间差是否超过访问时间的限制,如果超过了,则重置访问次数为1,否则增加访问次数。如果当前访问次数超过了访问次数的限制,则拒绝访问。
以下是一个简单的限流拦截器的代码:public class LimitInterceptor extends HandlerInterceptorAdapter { @Autowired private RedisTemplate redisTemplate; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String path = request.getRequestURI(); String key = LIMIT_KEY_PREFIX + path; BoundHashOperations boundHashOps = redisTemplate.boundHashOps(key); int count = boundHashOps.get("count"); int time = boundHashOps.get("time"); long currentTime = System.currentTimeMillis(); long lastTime = boundHashOps.get("lastTime"); if (lastTime == 0) { lastTime = currentTime; } if (currentTime - lastTime > time * 1000) { count = 1; } else { count++; } boundHashOps.put("count", count); boundHashOps.put("lastTime", (int) currentTime); if (count > limitCount) { response.setContentType("application/json;charset=utf-8"); response.getWriter().write("请求太频繁"); return false; } return true; } }
在上面的代码中,我们使用了BoundHashOperations类来操作Redis中的哈希表。BoundHashOperations是RedisTemplate的一个子类,可以更加方便地操作Redis中的哈希表。
我们在拦截器中,首先获取当前接口的路径,并根据路径获取当前接口的限流信息。然后,我们判断当前时间和上次访问时间的时间差是否超过访问时间的限制,如果超过了,则重置访问次数为1,否则增加访问次数。最后,如果当前访问次数超过了访问次数的限制,则拒绝访问。
最后,我们需要在Spring Boot中注册我们的限流拦截器。我们可以使用以下代码来注册拦截器:@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private LimitInterceptor limitInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(limitInterceptor); } }
在上面的代码中,我们创建了一个WebConfig类,并使用@Configuration注解来声明该类是一个配置类。然后,我们实现了WebMvcConfigurer接口,并重写了其中的addInterceptors方法。在该方法中,我们将我们的限流拦截器注册到了拦截器列表中。
现在,我们可以使用上面的代码来实现接口的限流了。当有用户请求某个接口时,我们会根据用户的IP地址和接口的路径来判断是否需要进行限流,如果需要进行限流,则根据接口的限流配置来判断是否拒绝请求。同时,我们还可以使用Redis的持久化功能来保证我们的限流信息不会因为服务器重启而丢失。
在实际应用中,我们还可以根据业务需求来调整接口的限流策略。例如,对于一些特殊的接口,我们可以将限流次数设置得更高,以保证这些接口能够稳定运行。同时,我们还可以使用一些工具来监控接口的访问情况,以便及时调整限流策略。总结
本文介绍了如何使用Spring Boot和Redis来实现接口的限流和防刷。通过使用Redis来存储限流信息,我们可以在分布式环境中方便地实现限流功能。同时,我们还可以根据业务需求来调整限流策略,以提高接口的可用性和稳定性。
需要注意的是,接口的限流和防刷只是保证接口能够正常运行的一种手段,我们还需要在代码中加入其他的安全措施,例如输入参数的校验、防SQL注入、防XSS攻击等。只有综合使用各种安全手段,才能有效地保障系统的安全性和稳定性。
下一篇内容我们来讨论一下接口防刷!
产科临床手册正式出版孕产妇死亡率是全球公认的衡量国民健康水平与社会进步的三大综合指标之一。2021年,中国孕产妇死亡率已下降至16。110万。但随着国家三胎政策的实施,高龄孕产妇比例增加,高危孕产妇管
承认错误!张伟丽正式向拳王泰森道歉抱歉怼了你北京时间1月6日,UFC冠军张伟丽接受了专访,也终于时隔1年多后,正式向拳王泰森进行了道歉。之前在与罗斯一番战比赛前,当时红极一时的张伟丽甚至怼过拳王泰森,对于泰森看好罗斯进行了回
杜锋重要决定!26岁悍将离队,易建联损失替补,19岁天才正式上位26岁的曾繁日本赛季的出场次数为0,起初被定义为养伤状态,腰部伤病复发,但根据国内媒体人透露,曾繁日目前已经离开广东,处于离队状态,不会出战本赛季的任何一场比赛。也就是,曾繁日正式
深圳乐高乐园地下桩基完工,三大主题酒店初见雏形选址深圳大鹏新区,全球最大的乐高乐园度假区日前迎来新进展!笔者获悉,目前,主题乐园地下桩基已完工,并已有序开展地面工程施工。其中,深圳乐高乐园度假区全新打造的三大主题酒店主体部分目
解锁跨年的N种方式,一起来云南跨年吧!2022进度条即将加载结束,2023也将开启新的一年。年将至,继行远,前路浩荡,万事可期。2023年第一站,一起来云南跨年吧!赏万家灯火璀璨,追寻新年第一缕阳光,奔赴大好河山。一起
伶仃岛上多繁华生态故事也盎然来源读特12月28日7时刚过,冉冉升起的一轮红日将笼罩在伶仃洋上的夜幕渐渐拂去。伴随着阵阵悦耳的鸟鸣,内伶仃岛正在晨风和海浪的轻抚中慢慢苏醒。迎着朝阳,广东内伶仃福田国家级自然保护
辉煌不再的客运站未来何去何从?城南旅游集散中心扩建后宽敞明亮在飞机高铁都不发达的年代,客运站曾是难以替代的存在。而现如今,高铁密织成网航线四通八达汽车保有量迅猛增长这些都让曾经辉煌一时的客运站客流量大幅下降。在
大城县臧屯镇任庄子村水果萝卜迎丰收村民正在采收成熟的水果萝卜。记者杨雅淇通讯员张增超摄大棚果蔬生长快,乡村采摘正当时。眼下在大城县臧屯镇任庄子村的大棚内,青翠嫣红的水果萝卜已经成熟,工人们忙着分拣装箱,一派丰收忙碌
12家!云南省级全域旅游示范区省级旅游度假区名单公示来源云南日报日前云南省文化和旅游厅发布关于拟认定6家单位为省级旅游度假区的公示及关于拟认定6家单位为省级全域旅游示范区的公示其中保山市腾冲市东山国家康养度假区等6家单位达到省级旅游
关于第一次进藏2022最难忘旅行这佛光闪闪的高原,三步两步便是天堂对拉萨持有执念,对藏北草原怀有海拔担忧,上班假期不够的我开启了我的西藏初映象6天5晚几乎每一个初次进藏的人,都说西藏真的太大了,
冰雪运动吹响冬季旅游复苏号角从重庆海拔最高滑雪场看冰雪体旅热起来27日,海拔2000多米的国家5A级景区重庆市南川区金佛山雪花纷飞,银装素裹。金佛山北坡滑雪场内,10岁的小朋友蹇雨辰正在雪道上感受滑雪的乐趣。自从女儿看了北京冬奥会,就一直想体验