电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Springboot使用redis實現接口Api限流的實例

瀏覽:14日期:2023-02-22 11:36:09
前言

Springboot使用redis實現接口Api限流的實例

該篇介紹的內容如題,就是利用redis實現接口的限流( 某時間范圍內 最大的訪問次數 ) 。

正文

慣例,先看下我們的實戰目錄結構:

Springboot使用redis實現接口Api限流的實例

首先是pom.xml 核心依賴:

<!--用于redis數據庫連接--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--用于redis lettuce 連接池pool使用--><dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>

然后是application.yml里面的redis接入配置:

spring: redis: lettuce: pool:#連接池最大連接數 使用負值代表無限制 默認為8max-active: 10#最大空閑連接 默認8max-idle: 10#最小空閑連接 默認0min-idle: 1 host: 127.0.0.1 password: 123456 port: 6379 database: 0 timeout: 2000msserver: port: 8710

redis的配置類, RedisConfig.java:

ps:可以看到日期是18年的,因為這些redis的整合教程,在這個系列里面一共有快10篇,不了解的看客如果感興趣可以去看一看。

import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.EnableCaching;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheConfiguration;import org.springframework.data.redis.cache.RedisCacheManager;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.RedisSerializationContext;import org.springframework.data.redis.serializer.StringRedisSerializer; import static org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConfig; /** * @Author: JCccc * @CreateTime: 2018-09-11 * @Description: */@Configuration@EnableCachingpublic class RedisConfig { @Bean public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {RedisCacheConfiguration cacheConfiguration =defaultCacheConfig().disableCachingNullValues().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer(Object.class)));return RedisCacheManager.builder(connectionFactory).cacheDefaults(cacheConfiguration).build(); } @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(factory);Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);//序列化設置 ,這樣為了存儲操作對象時正常顯示的數據,也能正常存儲和獲取redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);return redisTemplate; } @Bean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();stringRedisTemplate.setConnectionFactory(factory);return stringRedisTemplate; }}

自定義注解:

import java.lang.annotation.*; /** * @Author JCccc * @Description * @Date 2021/7/23 11:46 */@Inherited@Documented@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface RequestLimit { /** * 時間內 秒為單位 */ int second() default 10; /** * 允許訪問次數 */ int maxCount() default 5; //默認效果 : 10秒內 對于使用該注解的接口,只能總請求訪問數 不能大于 5次 }

接下來是攔截器 RequestLimitInterceptor.java:

攔截接口的方式 是通過 ip地址+接口url ,做時間內的訪問計數

import com.elegant.testdemo.annotation.RequestLimit;import com.elegant.testdemo.utils.IpUtil;import com.fasterxml.jackson.databind.ObjectMapper;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.concurrent.TimeUnit; /** * @Author JCccc * @Description * @Date 2021/7/23 11:49 */ @Componentpublic class RequestLimitInterceptor implements HandlerInterceptor { private final Logger log = LoggerFactory.getLogger(this.getClass()); @Autowired private RedisTemplate<String, Object> redisTemplate; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {try { if (handler instanceof HandlerMethod) {HandlerMethod handlerMethod = (HandlerMethod) handler;// 獲取RequestLimit注解RequestLimit requestLimit = handlerMethod.getMethodAnnotation(RequestLimit.class);if (null==requestLimit) { return true;}//限制的時間范圍int seconds = requestLimit.second();//時間內的 最大次數int maxCount = requestLimit.maxCount();String ipAddr = IpUtil.getIpAddr(request);// 存儲keyString key = ipAddr+':'+request.getContextPath() + ':' + request.getServletPath();// 已經訪問的次數Integer count = (Integer) redisTemplate.opsForValue().get(key);log.info('檢測到目前ip對接口={}已經訪問的次數', request.getServletPath() , count);if (null == count || -1 == count) { redisTemplate.opsForValue().set(key, 1, seconds, TimeUnit.SECONDS); return true;}if (count < maxCount) { redisTemplate.opsForValue().increment(key); return true;}log.warn('請求過于頻繁請稍后再試');returnData(response);return false; } return true;} catch (Exception e) { log.warn('請求過于頻繁請稍后再試'); e.printStackTrace();}return true; } public void returnData(HttpServletResponse response) throws IOException {response.setCharacterEncoding('UTF-8');response.setContentType('application/json; charset=utf-8');ObjectMapper objectMapper = new ObjectMapper();//這里傳提示語可以改成自己項目的返回數據封裝的類response.getWriter().println(objectMapper.writeValueAsString('請求過于頻繁請稍后再試'));return; } }

接下來是 攔截器的配置 WebConfig.java:

import com.elegant.testdemo.interceptor.RequestLimitInterceptor;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @Author JCccc * @Description * @Date 2021/7/23 11:52 */ @Configurationpublic class WebConfig implements WebMvcConfigurer { @Autowired private RequestLimitInterceptor requestLimitInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(requestLimitInterceptor) //攔截所有請求路徑.addPathPatterns('/**')//再設置 放開哪些路徑.excludePathPatterns('/static/**','/auth/login'); } }

最后還有兩個工具類

IpUtil:

https://www.jb51.net/article/218249.htm

RedisUtil :

https://www.jb51.net/article/218246.htm

最后寫個測試接口

TestController.java

import com.elegant.testdemo.annotation.RequestLimit;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController; /** * @Author JCccc * @Description * @Date 2021/7/23 11:55 */@RestControllerpublic class TestController { @GetMapping('/test') @RequestLimit(maxCount = 3,second = 60) public String test() {return '你好,如果對你有幫助,請點贊加關注。'; } }

這個/test接口的注解,我們設置的是 60秒內 最大訪問次數為 3次 (實際應用應該是根據具體接口做相關的次數限制。)

然后使用postman測試一下接口:

前面三次都是請求通過的:

Springboot使用redis實現接口Api限流的實例

Springboot使用redis實現接口Api限流的實例

第四次:

Springboot使用redis實現接口Api限流的實例

到此這篇關于Springboot使用redis實現接口Api限流的實例的文章就介紹到這了,更多相關Springboot redis接口Api限流內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
主站蜘蛛池模板: HEYL硬度计量泵-荧光法在线溶解氧仪-净时测控技术(上海)有限公司 | 钢化玻璃膜|手机钢化膜|钢化膜厂家|手机保护膜-【东莞市大象电子科技有限公司】 | 河南新乡德诚生产厂家主营震动筛,振动筛设备,筛机,塑料震动筛选机 | 解放卡车|出口|济南重汽|报价大全|山东三维商贸有限公司 | 高中学习网-高考生信息学习必备平台| 一体化污水处理设备-一体化净水设备-「山东梦之洁水处理」 | 辐射色度计-字符亮度测试-反射式膜厚仪-苏州瑞格谱光电科技有限公司 | 液压油缸-液压站生产厂家-洛阳泰诺液压科技有限公司 | 校车_校车价格_19座幼儿园校车_幼儿园校车_大鼻子校车 | 台式低速离心机-脱泡离心机-菌种摇床-常州市万丰仪器制造有限公司 | 污水/卧式/潜水/钻井/矿用/大型/小型/泥浆泵,价格,参数,型号,厂家 - 安平县鼎千泵业制造厂 | 雾度仪_雾度计_透光率雾度仪价格-三恩时(3nh)光电雾度仪厂家 | 通风气楼_通风天窗_屋顶风机-山东美创通风设备有限公司 | 即用型透析袋,透析袋夹子,药敏纸片,L型涂布棒-上海桥星贸易有限公司 | 耐压仪-高压耐压仪|徐吉电气| 复合土工膜厂家|hdpe防渗土工膜|复合防渗土工布|玻璃纤维|双向塑料土工格栅-安徽路建新材料有限公司 | 烟台螺纹,烟台H型钢,烟台钢材,烟台角钢-烟台市正丰金属材料有限公司 | 排烟防火阀-消防排烟风机-正压送风口-厂家-价格-哪家好-德州鑫港旺通风设备有限公司 | 不锈钢搅拌罐_高速搅拌罐厂家-无锡市凡格德化工装备科技有限公司 | 医用空气消毒机-医用管路消毒机-工作服消毒柜-成都三康王 | 河南空气能热水器-洛阳空气能采暖-洛阳太阳能热水工程-洛阳润达高科空气能商行 | 阻垢剂,反渗透阻垢剂,缓蚀阻垢剂-山东普尼奥水处理科技有限公司 真空粉体取样阀,电动楔式闸阀,电动针型阀-耐苛尔(上海)自动化仪表有限公司 | 闭端端子|弹簧螺式接线头|防水接线头|插线式接线头|端子台|电源线扣+护线套|印刷电路板型端子台|金笔电子代理商-上海拓胜电气有限公司 | 细胞染色-流式双标-试剂盒免费代做-上海研谨生物科技有限公司 | 岩石钻裂机-液压凿岩机-劈裂机-挖改钻_湖南烈岩科技有限公司 | 噪声治理公司-噪音治理专业隔音降噪公司 | 开业庆典_舞龙舞狮_乔迁奠基仪式_开工仪式-神挚龙狮鼓乐文化传媒 | 砂磨机_立式纳米砂磨机_实验室砂磨机-广州儒佳化工设备厂家 | 数显恒温培养摇床-卧式/台式恒温培养摇床|朗越仪器 | 西点培训学校_法式西点培训班_西点师培训_西点蛋糕培训-广州烘趣西点烘焙培训学院 | LED灯杆屏_LED广告机_户外LED广告机_智慧灯杆_智慧路灯-太龙智显科技(深圳)有限公司 | 招商帮-一站式网络营销服务|搜索营销推广|信息流推广|短视视频营销推广|互联网整合营销|网络推广代运营|招商帮企业招商好帮手 | 环球电气之家-中国专业电气电子产品行业服务网站! | 荣事达手推洗地机_洗地机厂家_驾驶式扫地机_工业清洁设备 | 电脑刺绣_绣花厂家_绣花章仔_织唛厂家-[源欣刺绣]潮牌刺绣打版定制绣花加工厂家 | 乙炔气体报警装置|固定式氯化氢检测仪|河南驰诚电气百科 | 青岛侦探_青岛侦探事务所_青岛劝退小三_青岛调查出轨取证公司_青岛婚外情取证-青岛探真调查事务所 | 众品地板网-地板品牌招商_地板装修设计_地板门户的首选网络媒体。 | 知企服务-企业综合服务(ZiKeys.com)-品优低价、种类齐全、过程管理透明、速度快捷高效、放心服务,知企专家! | 阀门智能定位器_电液动执行器_气动执行机构-赫尔法流体技术(北京)有限公司 | 螺旋绞龙叶片,螺旋输送机厂家,山东螺旋输送机-淄博长江机械制造有限公司 |