
在開發分布式高並發系統時有三把利器用來保護系統:緩存、降級、限流。
緩存緩存的目的是提升系統訪問速度和增大系統處理容量
降級降級是當服務出現問題或者影響到核心流程時,需要暫時屏蔽掉,待高峰或者問題解決後再打開
限流限流的目的是通過對並發訪問/請求進行限速,或者對一個時間窗口內的請求進行限速來保護系統,一旦達到限制速率則可以拒絕服務、排隊或等待、降級等處理
本文主要講的是api接口限流相關內容,雖然不是論述高並發概念中的限流, 不過道理都差不多。通過限流可以讓系統維持在一個相對穩定的狀態,為更多的客戶提供服務。
api接口的限流主要應用場景有:
SpringBoot中集成Redis相對比較簡單,步驟如下:
1.1 引入Redis依賴
<!--springbootredis依賴--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>1.2 在application.yml中配置Redis
spring:redis:database:3#Redis數據庫索引(默認為0)host:127.0.0.1#Redis服務器地址port:6379#Redis服務器連接端口password:123456#Redis服務器連接密碼(默認為空)timeout:2000#連接超時時間(毫秒)jedis:pool:max-active:200#連接池最大連接數(使用負值表示沒有限制)max-idle:20#連接池中的最大空閒連接min-idle:0#連接池中的最小空閒連接max-wait:-1#連接池最大阻塞等待時間(使用負值表示沒有限制)1.3 配置RedisTemplate
/***@Description:redis配置類*@Authoroyc*/@Configuration@EnableCachingpublicclassRedisConfigextendsCachingConfigurerSupport{/***RedisTemplate相關配置*使redis支持插入對象**@paramfactory*@return方法緩存Methodsthecache*/@BeanpublicRedisTemplate<String,Object>redisTemplate(RedisConnectionFactoryfactory){RedisTemplate<String,Object>template=newRedisTemplate<>();//配置連接工廠template.setConnectionFactory(factory);//設置key的序列化器template.setKeySerializer(newStringRedisSerializer());//設置value的序列化器//使用Jackson2,將對象序列化為JSONJackson2JsonRedisSerializerjackson2JsonRedisSerializer=newJackson2JsonRedisSerializer(Object.class);//json轉對象類,不設置默認的會將json轉成hashmapObjectMapperom=newObjectMapper();om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);template.setValueSerializer(jackson2JsonRedisSerializer);returntemplate;}}以上,已經完成Redis的集成,後續使用可以直接注入RedisTemplate,如下所示:
@AutowiredprivateRedisTemplate<String,Object>redisTemplate;二、實現限流2.1 添加自定義AccessLimit註解
使用註解方式實現接口的限流操作,方便而優雅。
/***@Description:*@Authoroyc*/@Inherited@Documented@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public@interfaceAccessLimit{/***指定second時間內API請求次數*/intmaxCount()default5;/***請求次數的指定時間範圍秒數(redis數據過期時間)*/intsecond()default60;}2.2 編寫攔截器
限流的思路
2.3 註冊攔截器並配置攔截路徑和不攔截路徑
/***@Description:訪問攔截器配置*@Authoroyc*@Date2020/10/2211:34下午*/@ConfigurationpublicclassIntercepterConfigimplementsWebMvcConfigurer{@AutowiredprivateAccessLimitInterceptoraccessLimitInterceptor;@OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){registry.addInterceptor(accessLimitInterceptor).addPathPatterns("/**").excludePathPatterns("/static/**","/login.html","/user/login");}}2.4 使用AccessLimit
/***@Description:*@Authoroyc*/@RestController@RequestMapping("access")publicclassAccessLimitController{privatefinalLoggerlogger=LoggerFactory.getLogger(this.getClass());/***限流測試*/@GetMapping@AccessLimit(maxCount=3,second=60)publicStringlimit(HttpServletRequestrequest){logger.error("AccessLimitTest");return"限流測試";}}2.5 測試

源碼傳送門:
https://github.com/oycyqr/springboot-learning-demo/tree/master/springboot-validated
來源:blog.csdn.net/u014553029/article/details/109232225
END
關注後端面試那些事,回復【2022面經】
獲取最新大廠Java面經

