1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        SpringBoot+Redis實(shí)現(xiàn)接口限流

        共 5358字,需瀏覽 11分鐘

         ·

        2022-03-03 01:00

        在這之前對(duì)redis一無(wú)所知,做的過(guò)程都是參考網(wǎng)上的資料,如果有冒犯之處請(qǐng)見(jiàn)諒,整理一下,希望對(duì)大家都用。

        1.使用maven添加依賴庫(kù),本項(xiàng)目中使用的是:
        <dependency>
        ???<groupId>org.springframework.bootgroupId>
        ???<artifactId>spring-boot-starter-data-redisartifactId>
        ???<version>2.1.4.RELEASEversion>
        dependency>
        2.配置redis服務(wù)

        下載地址:

        https://github.com/MicrosoftArchive/redis/releases

        下載完成后啟動(dòng)即可

        linux安裝教程可參考:

        https://blog.csdn.net/fm_vae/article/details/80234340

        3.回到正題,目的是使用redis達(dá)到接口限流的效果。

        定義一個(gè)注解標(biāo)明需要使用限流的接口

        @Retention(RUNTIME)
        @Target(METHOD)
        public?@interface?AccessLimit?{
        ?
        ????int?seconds();
        ????int?maxCount();
        }

        在springboot的攔截器中,如果你沒(méi)有配置攔截器,需要自定義類繼承HandlerInterceptor,

        ??@Override
        ????public?boolean?preHandle(HttpServletRequest?httpServletRequest,?HttpServletResponse?httpServletResponse,?Object?handler)?throws?Exception?{
        ????????//如果請(qǐng)求輸入方法
        ????????if?(handler?instanceof?HandlerMethod)?{
        ????????????HandlerMethod?hm?=?(HandlerMethod)?handler;
        ????????????//獲取方法中的注解,看是否有該注解
        ????????????AccessLimit?accessLimit?=?hm.getMethodAnnotation(AccessLimit.class);
        ????????????if?(accessLimit?!=?null)?{
        ????????????????long?seconds?=?accessLimit.seconds();
        ????????????????int?maxCount?=?accessLimit.maxCount();
        //關(guān)于key的生成規(guī)則可以自己定義?本項(xiàng)目需求是對(duì)每個(gè)方法都加上限流功能,如果你只是針對(duì)ip地址限流,那么key只需要只用ip就好
        ????????????????String?key?=?????SystemUtil.getClientIp(httpServletRequest)+hm.getMethod().getName();
        ??????????????
        ????????????????//從redis中獲取用戶訪問(wèn)的次數(shù)
        ????????????????try?{
        ????????????????????long?q?=?redisService.incr(key,?seconds);//此操作代表獲取該key對(duì)應(yīng)的值自增1后的結(jié)果
        ????????????????????if?(q?>?maxCount)?{
        ????????????????????????//加1
        ????????????????????????render(httpServletResponse,?new?ResponseMsg(0,?"請(qǐng)求過(guò)于頻繁,請(qǐng)稍候再試",?null));?//這里的CodeMsg是一個(gè)返回參數(shù)
        ????????????????????????return?false;
        ????????????????????}
        ????????????????????return?true;
        ????????????????}catch?(RedisConnectionFailureException?e){
        ????????????????????logger.info("redis錯(cuò)誤"+e.getMessage().toString());
        ????????????????????return?true;
        ????????????????}
        ????????????}
        ?
        ????????}
        ?
        ?
        ????????return?false;
        ????}
        ?
        ????private?void?render(HttpServletResponse?response,?ResponseMsg?cm)?throws?Exception?{
        ????????response.setContentType("application/json;charset=UTF-8");
        ????????OutputStream?out?=?response.getOutputStream();
        ????????String?str?=?new?Gson().toJson(cm);
        ????????out.write(str.getBytes("UTF-8"));
        ????????out.flush();
        ????????out.close();
        ????}

        上面使用到的redisservice

        public?interface??RedisService?{
        ?
        ????/**
        ?????*?set存數(shù)據(jù)
        ?????*?@param?key
        ?????*?@param?value
        ?????*?@return
        ?????*/

        ????boolean?set(String?key,?String?value);
        ?
        ????/**
        ?????*?get獲取數(shù)據(jù)
        ?????*?@param?key
        ?????*?@return
        ?????*/

        ????String?get(String?key);
        ?
        ????/**
        ?????*?設(shè)置有效天數(shù)
        ?????*?@param?key
        ?????*?@param?expire
        ?????*?@return
        ?????*/

        ????boolean?expire(String?key,?long?expire);
        ?
        ????/**
        ?????*?移除數(shù)據(jù)
        ?????*?@param?key
        ?????*?@return
        ?????*/

        ????boolean?remove(String?key);
        ?
        ????/**
        ?????*?獲取自增1后的?值
        ?????*?@param?key
        ?????*?@param?time
        ?????*?@return
        ?????*/

        ????Long?incr(String?key,long?time);
        }

        redisservice的實(shí)現(xiàn)類

        @Service("redisService")
        public?class?RedisServiceImpl?implements?RedisService?{
        ?
        ?
        ????@Resource
        ????private?RedisTemplate?redisTemplate;
        ?
        ?
        ????@Override
        ????public?boolean?set(final?String?key,?final?String?value)?{
        ????????boolean?result?=?redisTemplate.execute(new?RedisCallback()?{
        ????????????@Override
        ????????????public?Boolean?doInRedis(RedisConnection?connection)?throws?DataAccessException?{
        ????????????????RedisSerializer?serializer?=?redisTemplate.getStringSerializer();
        ????????????????connection.set(serializer.serialize(key),?serializer.serialize(value));
        ????????????????return?true;
        ????????????}
        ????????});
        ????????return?result;
        ????}
        ?
        ????@Override
        ????public?String?get(final?String?key)?{
        ????????String?result?=?redisTemplate.execute(new?RedisCallback()?{
        ????????????@Override
        ????????????public?String?doInRedis(RedisConnection?connection)?throws?DataAccessException?{
        ????????????????RedisSerializer?serializer?=?redisTemplate.getStringSerializer();
        ????????????????byte[]?value?=?connection.get(serializer.serialize(key));
        ????????????????return?serializer.deserialize(value);
        ????????????}
        ????????});
        ????????return?result;
        ????}
        ?
        ????@Override
        ????public?boolean?expire(final?String?key,?long?expire)?{
        ????????return?redisTemplate.expire(key,?expire,?TimeUnit.SECONDS);
        ????}
        ?
        ????@Override
        ????public?boolean?remove(final?String?key)?{
        ????????boolean?result?=?redisTemplate.execute(new?RedisCallback()?{
        ????????????@Override
        ????????????public?Boolean?doInRedis(RedisConnection?connection)?throws?DataAccessException?{
        ????????????????RedisSerializer?serializer?=?redisTemplate.getStringSerializer();
        ????????????????connection.del(key.getBytes());
        ????????????????return?true;
        ????????????}
        ????????});
        ????????return?result;
        ????}
        ????@Override
        ????public?Long?incr(String?key,long?time){
        ????????long?count?=?redisTemplate.opsForValue().increment(key,?1);
        ????????if?(count?==?1)?{
        ????????????//設(shè)置有效期一分鐘
        ????????????set(key,"1");
        ????????????redisTemplate.expire(key,?time,?TimeUnit.SECONDS);
        ????????}
        ????????return?count;
        ????}
        }

        至此限流的準(zhǔn)備工作都做完了,測(cè)試一下ok,在controller方法中加上如下注解即可

        @AccessLimit(seconds=second,?maxCount=maxCount)

        測(cè)試通過(guò)。

        代碼大部分是從網(wǎng)上copy過(guò)來(lái)的,我只是整理了一下,因?yàn)槲沂歉袅撕镁貌耪淼?,至于copy的哪位大神的代碼我找不到了,如有冒犯,請(qǐng)見(jiàn)諒!

        來(lái)源:blog.csdn.net/qq_34963282/article/

        details/89489009


        END


        推薦閱讀

        一鍵生成Springboot & Vue項(xiàng)目!【畢設(shè)神器】

        Java可視化編程工具系列(一)

        Java可視化編程工具系列(二)


        順便給大家推薦一個(gè)GitHub項(xiàng)目,這個(gè) GitHub 整理了上千本常用技術(shù)PDF,絕大部分核心的技術(shù)書籍都可以在這里找到,

        GitHub地址:https://github.com/javadevbooks/books

        電子書已經(jīng)更新好了,你們需要的可以自行下載了,記得點(diǎn)一個(gè)star,持續(xù)更新中..



        瀏覽 41
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            杂技全黄一级A片 | 一级卖婬片AAAA片爱奴 | 巴西2一3sex性hd | 夫妻超碰自拍 | 久久久欧美成人片免费看网站主播 | 欧美熟妇性又伦-区二区 | 91探花国产综合在线精品最新章节 | 麻豆精品免费观看 | 99re亚洲| 中文字幕自拍偷拍 |