<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring Boot 如何使用 Redis 進行 API 防刷限流?

          共 3645字,需瀏覽 8分鐘

           ·

          2020-09-13 11:37

          Java技術棧

          www.javastack.cn

          關注閱讀更多優(yōu)質(zhì)文章



          限流的需求出現(xiàn)在許多常見的場景中:

          API 限流實戰(zhàn)

          首先我們編寫注解類AccessLimit,使用注解方式在方法上限流更優(yōu)雅更方便!Spring Boot 如何集成 Redis 請點擊這里進行閱讀。

          三個參數(shù)分別代表有效時間、最大訪問次數(shù)、是否需要登錄,可以理解為 seconds 內(nèi)最多訪問 maxCount 次。

          import?java.lang.annotation.ElementType;
          import?java.lang.annotation.Retention;
          import?java.lang.annotation.RetentionPolicy;
          import?java.lang.annotation.Target;

          @Retention(RetentionPolicy.RUNTIME)
          @Target(ElementType.METHOD)
          public?@interface?AccessLimit?{
          ????int?seconds();
          ????int?maxCount();
          ????boolean?needLogin()?default?true;
          }

          限流的思路:

          • 通過路徑:ip的作為key,訪問次數(shù)為value的方式對某一用戶的某一請求進行唯一標識

          • 每次訪問的時候判斷key是否存在,是否count超過了限制的訪問次數(shù)

          • 若訪問超出限制,則應response返回msg:請求過于頻繁給前端予以展示

          import?org.springframework.beans.factory.annotation.Autowired;
          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;

          @Component
          public?class?AccessLimtInterceptor?implements?HandlerInterceptor?{

          ????@Autowired
          ????private?RedisService?redisService;

          ????@Override
          ????public?boolean?preHandle(HttpServletRequest?request,?HttpServletResponse?response,?Object?handler)?throws?Exception?{

          ????????if?(handler?instanceof?HandlerMethod)?{
          ????????????HandlerMethod?hm?=?(HandlerMethod)?handler;
          ????????????AccessLimit?accessLimit?=?hm.getMethodAnnotation(AccessLimit.class);
          ????????????if?(null?==?accessLimit)?{
          ????????????????return?true;
          ????????????}
          ????????????int?seconds?=?accessLimit.seconds();
          ????????????int?maxCount?=?accessLimit.maxCount();
          ????????????boolean?needLogin?=?accessLimit.needLogin();

          ????????????if?(needLogin)?{
          ????????????????//判斷是否登錄
          ????????????}

          ????????????String?key?=?request.getContextPath()?+?":"?+?request.getServletPath()?+?":"?+?ip?;

          ????????????Integer?count?=?redisService.get(key);

          ????????????if?(null?==?count?||?-1?==?count)?{
          ????????????????redisService.set(key,?1);
          ????????????????redisService.expire(seconds);
          ????????????????return?true;
          ????????????}

          ????????????if?(count?????????????????redisService.inCr(key);
          ????????????????return?true;
          ????????????}

          ????????????if?(count?>=?maxCount)?{
          //????????????????response?返回?json?請求過于頻繁請稍后再試
          ????????????????return?false;
          ????????????}
          ????????}

          ????????return?true;
          ????}
          }

          注冊攔截器并配置攔截路徑和不攔截路徑:

          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;

          //?extends?WebMvcConfigurerAdapter?已經(jīng)廢棄,java?8開始直接繼承就可以
          @Configuration
          public?class?IntercepterConfig??implements?WebMvcConfigurer?{
          ????@Autowired
          ????private?AccessLimtInterceptor?accessLimtInterceptor;

          ????@Override
          ????public?void?addInterceptors(InterceptorRegistry?registry)?{
          ????????registry.addInterceptor(accessLimtInterceptor)
          ????????????????.addPathPatterns("/攔截路徑")
          ????????????????.excludePathPatterns("/不被攔截路徑?通常為登錄注冊或者首頁");
          ????}
          }

          Controller層的方法上直接可以使用注解@AccessLimit

          import?org.springframework.web.bind.annotation.GetMapping;
          import?org.springframework.web.bind.annotation.RequestMapping;
          import?org.springframework.web.bind.annotation.RestController;

          @RestController
          @RequestMapping("test")
          public?class?TestControler?{

          ????@GetMapping("accessLimit")
          ????@AccessLimit(seconds?=?3,?maxCount?=?10)
          ????public?String?testAccessLimit()?{
          ????????//xxxx
          ????????return?"";
          ????}
          }


          作者:海向

          出處:cnblogs.com/haixiang/p/12012728.html





          關注Java技術??锤喔韶?/strong>



          戳原文,獲取更多福利!
          瀏覽 33
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  3p两根一起进女学生 | 菠萝 成人网站视频 | 青青草男人的天堂 | 免费观看性欧美一级 | 婷婷激情在线发布 |