应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

接口的屏蔽和限流很难么?Redis全搞定

  需求
  线上出现的问题是,一些非核心的查询数据业务,在请求超时或者错误的时候,用户会越查询,导致数据库cup飙升,拖垮核心的业务。
  领导让我做三件事,一是把这些接口做一个限流,这些限流参数是可配的,第二是这些接口可以设置开关,当发现问题时,可以手动关闭这些接口,不至于数据库压力过大影响核心业务的服务。第三是做接口的熔断,熔断设置可以配置。
  经过确定,前两个实现用redis来实现,第三个因为熔断讨论觉得比较复杂,决定采用我提出的用Hystrix,目前项目不能热加载生效配置中心的最新的配置,所以后期推荐使用Archaius,这些网上查到的,具体为啥不选其他的,原因就是其他的比较复杂,上手感觉这个最快。
  这篇文章说实现,其他问题不涉及,请多多指教。思路
  接口的屏蔽:通过AOP实现,每次访问接口的时候,通过接口的Key值,在Redis取到接口设置开关值,如果打开继续,否在拒绝。接口限流也是基于AOP,根据接口的Key值,取到这个接口的限流值,表示多长时间,限流几次,每次访问都会请求加一,通过比较,如果超过限制再返回,否在继续。代码
  AccessLimiter接口,主要有两类方法,是否开启限流,取Redis中的限流值。packagecom。hcfc。auto。util。limit;importjava。util。concurrent。TimeUnit;创建人peng。wang描述访问限制器publicinterfaceAccessLimiter{检查指定的key是否收到访问限制paramkey限制接口的标识paramtimes访问次数paramper一段时间paramunit时间单位returnpublicbooleanisLimited(Stringkey,longtimes,longper,TimeUnitunit);移除访问限制paramkeypublicvoidrefreshLimited(Stringkey);接口是否打开returnpublicbooleanisStatus(StringredisKey);接口的限流大小paramredisKeyTimesreturnpubliclonggetTimes(StringredisKeyTimes);接口限流时间段paramredisKeyPerreturnpubliclonggetPer(StringredisKeyPer);接口的限流时间单位paramredisKeyUnitreturnpublicTimeUnitgetUnit(StringredisKeyUnit);是否删除接口限流paramredisKeyIsRefreshreturnpublicbooleangetIsRefresh(StringredisKeyIsRefresh);}
  RedisAccessLimiter是AccessLimiter接口的实现类packagecom。hcfc。auto。util。limit;importorg。slf4j。Logger;importorg。slf4j。LoggerFactory;importorg。springframework。beans。factory。annotation。Autowired;importorg。springframework。data。redis。core。RedisTemplate;importorg。springframework。stereotype。Component;importjava。util。concurrent。TimeUnit;创建人peng。wang描述基于Redis的实现ComponentpublicclassRedisAccessLimiterimplementsAccessLimiter{privatestaticfinalLoggerLOGGERLoggerFactory。getLogger(RedisAccessLimiter。class);AutowiredprivateRedisTemplateredisTemplate;OverridepublicbooleanisLimited(Stringkey,longtimes,longper,TimeUnitunit){LongcurTimesredisTemplate。boundValueOps(key)。increment(1);LOGGER。info(curTimes{},curTimes);if(curTimestimes){LOGGER。debug(超频访问:〔{}〕,key);returntrue;}else{if(curTimes1){LOGGER。info(setexpire);redisTemplate。boundValueOps(key)。expire(per,unit);returnfalse;}else{returnfalse;}}}OverridepublicvoidrefreshLimited(Stringkey){redisTemplate。delete(key);}OverridepublicbooleanisStatus(StringredisKey){try{return(boolean)redisTemplate。opsForValue()。get(redisKeyIsOn);}catch(Exceptione){LOGGER。info(redisKeyisnotfindortypemismatch,key:,redisKey);returnfalse;}}OverridepubliclonggetTimes(StringredisKeyTimes){try{return(long)redisTemplate。opsForValue()。get(redisKeyTimesTimes);}catch(Exceptione){LOGGER。info(redisKeyisnotfindortypemismatch,key:,redisKeyTimes);return0;}}OverridepubliclonggetPer(StringredisKeyPer){try{return(long)redisTemplate。opsForValue()。get(redisKeyPerPer);}catch(Exceptione){LOGGER。info(redisKeyisnotfindortypemismatch,key:,redisKeyPer);return0;}}OverridepublicTimeUnitgetUnit(StringredisKeyUnit){try{return(TimeUnit)redisTemplate。opsForValue()。get(redisKeyUnitUnit);}catch(Exceptione){LOGGER。info(redisKeyisnotfindortypemismatch,key:,redisKeyUnit);returnTimeUnit。SECONDS;}}OverridepublicbooleangetIsRefresh(StringredisKeyIsRefresh){try{return(boolean)redisTemplate。opsForValue()。get(redisKeyIsRefreshIsRefresh);}catch(Exceptione){LOGGER。info(redisKeyisnotfindortypemismatch,key:,redisKeyIsRefresh);returnfalse;}}}
  Limit标签接口,实现注解方式packagecom。hcfc。auto。util。limit;importjava。lang。annotation。;创建人peng。wang描述Target({ElementType。METHOD,ElementType。ANNOTATIONTYPE})Retention(RetentionPolicy。RUNTIME)DocumentedpublicinterfaceLimit{}
  LimitAspect切面的实现,实现接口屏蔽和限流的逻辑packagecom。hcfc。auto。util。limit;importcom。hcfc。auto。vo。response。ResponseDto;importlombok。extern。slf4j。Slf4j;importorg。aspectj。lang。ProceedingJoinPoint;importorg。aspectj。lang。annotation。Around;importorg。aspectj。lang。annotation。Aspect;importorg。aspectj。lang。annotation。Pointcut;importorg。aspectj。lang。reflect。MethodSignature;importorg。slf4j。Logger;importorg。slf4j。LoggerFactory;importorg。springframework。beans。factory。annotation。Autowired;importorg。springframework。stereotype。Component;importorg。springframework。web。bind。annotation。RequestMapping;importjava。lang。reflect。Method;importjava。util。concurrent。TimeUnit;创建人peng。wang创建时间20191011描述Slf4jAspectComponentpublicclassLimitAspect{privatestaticfinalLoggerloggerLoggerFactory。getLogger(LimitAspect。class);AutowiredprivateAccessLimiterlimiter;AutowiredGenerateRedisKeygenerateRedisKey;Pointcut(annotation(com。hcfc。auto。util。limit。Limit))publicvoidlimitPointcut(){}Around(limitPointcut())publicObjectdoArround(ProceedingJoinPointjoinPoint)throwsThrowable{StringredisKeygenerateRedisKey。getMethodUrlConvertRedisKey(joinPoint);longperlimiter。getPer(redisKey);longtimeslimiter。getTimes(redisKey);TimeUnitunitlimiter。getUnit(redisKey);booleanisRefreshlimiter。getIsRefresh(redisKey);booleanmethodLimitStatuslimiter。isStatus(redisKey);StringbindingKeygenBindingKey(joinPoint);if(methodLimitStatus){logger。info(methodisclosed,key:,bindingKey);returnResponseDto。fail(40007,methodisclosed,key:bindingKey);thrownewOverLimitException(methodisclosed,key:bindingKey);}if(bindingKey!null){booleanisLimitedlimiter。isLimited(bindingKey,times,per,unit);if(isLimited){logger。info(limittakeseffect:{},bindingKey);returnResponseDto。fail(40006,accessoverlimit,key:bindingKey);thrownewOverLimitException(accessoverlimit,key:bindingKey);}}Objectresultnull;resultjoinPoint。proceed();if(bindingKey!nullisRefresh){limiter。refreshLimited(bindingKey);logger。info(limitrefreshed:{},bindingKey);}returnresult;}privateStringgenBindingKey(ProceedingJoinPointjoinPoint){try{Methodm((MethodSignature)joinPoint。getSignature())。getMethod();returnjoinPoint。getTarget()。getClass()。getName()。m。getName();}catch(Throwablee){returnnull;}}}
  还有一个不重要的RedisKey实现类GenerateRedisKey和一个错误封装类,目前没有使用到,使用项目中其他的错误封装类了。
  GenerateRedisKeypackagecom。hcfc。auto。util。limit;importorg。aspectj。lang。ProceedingJoinPoint;importorg。aspectj。lang。reflect。MethodSignature;importorg。springframework。stereotype。Component;importorg。springframework。web。bind。annotation。RequestMapping;importjava。lang。reflect。Method;创建人peng。wang描述ComponentpublicclassGenerateRedisKey{publicStringgetMethodUrlConvertRedisKey(ProceedingJoinPointjoinPoint){StringBuilderredisKeynewStringBuilder();Methodm((MethodSignature)joinPoint。getSignature())。getMethod();RequestMappingmethodAnnotationm。getAnnotation(RequestMapping。class);if(methodAnnotation!null){String〔〕methodValuemethodAnnotation。value();StringdscUrldiagonalLineToCamel(methodValue〔0〕);returnredisKey。append(RSK:)。append(interfaceIsOpen:)。append(dscUrl)。toString();}returnredisKey。toString();}privateStringdiagonalLineToCamel(Stringparam){charUNDERLINE;if(paramnull。equals(param。trim())){return;}intlenparam。length();StringBuildersbnewStringBuilder(len);for(inti1;ilen;i){charcparam。charAt(i);if(cUNDERLINE){if(ilen){sb。append(Character。toUpperCase(param。charAt(i)));}}else{sb。append(c);}}returnsb。toString();}}总结
  关键的代码也就这几行,访问之前,对这个key值加一的操作,判断是否超过限制,如果等于一这个key加一之后的值为一,说明之前不存在,则设置这个key,放在Redis数据库中。
  其实有更成熟的方案就是谷歌的Guava,领导说现在是咱们是分布式,不支持,还是用Redis实现吧,目前就这样实现了。其实我是新来的,好多东西还不太明白,很多决定都是上面决定的,我只是尽力实现罢了。不足之处,请多多指教!作者:IngramMSN
  来源:blog。csdn。netu010843114articledetails102695570

1927年的建军大业,共走出九大元帅1927年的建军大业,共走出九大元帅!十大元帅1927年对我军来说是创世纪的一年,这一年人民武装正式成立,揭竿而起,反对国民党的统治。建军大业共包括三大起义:……刁蛮公主配角再度翻红,而主角却因作死被封杀?要说起关于十四年前经典搞笑古装剧,那就必须就要提一下《刁蛮公主》。当初这部剧,可是火遍了全国,几乎是每家每户都在追着,甚至三刷四刷,都不为过。可爱调皮的公主,遇上大帅哥级别皇帝……蒋勤勤大口吃盒饭被拍,素颜老成这样,明星不包装还认得出来吗?蒋勤勤真的是非常的老了,虽然说她现在正版的气质已经真的是非常的憔悴,就连包装都认不出来了,原来明星都是靠包装的,因为毕竟蒋勤勤们是要上镜的,所以肯定是要通过后期大量的修图或者是……江山如此多娇,万水千山走遍(内蒙篇)地处中国北部,横跨东北、华北、西北地区的内蒙古自治区,简称蒙,首府呼和浩特。东北部与黑龙江、吉林、辽宁、河北交界,南部与山西、陕西、宁夏相邻,西南部与甘肃毗连,北部与俄罗斯、蒙……站车顶维权女车主起诉特斯拉案开庭,当事人被激怒了,想证明自己12月24日上午,进入上海车展站在车顶高呼特斯拉刹车失灵的维权车主张女士起诉特斯拉(上海)有限公司、特斯拉汽车(北京)有限公司、特斯拉公司全球副总裁陶琳名誉权纠纷一案,在河南省……大胜雄鹿29分!骑士6连胜进前三追赶篮网,火箭弃帅立功了12月19日,骑士客场119比90大胜雄鹿29分,豪取6连胜,球队战绩19胜12负升到东部第三,距离篮网只剩下2。5个胜场差距。篮网三巨头都触发健康安全协议,战斗力严重打折,骑……不给就退车!高通8155芯片到底有何魅力?前段时间,欧拉汽车因为把好猫车型的车机芯片从高通8155偷换成英特尔Atom3940芯片,引起了轩然大波,不仅被央视点名批评,很多车主还要求不给换8155芯片就退车!那么……去屑洗发水真的能去屑吗?有的洗发水用了之后为什么会有头屑?发现自己有头屑,很多人的第一反应就是在网上搜一搜去屑洗发水,选个牌子就结束了,可是洗来洗去发现还是有头屑,甚至本来没有头屑,用了某一洗发水后突然有头屑了,这到底是怎么一回事?去……光遇高马尾YYDS,复刻可以分期?蜡烛少的人这样做光遇:高马尾YYDS,复刻可以分期?蜡烛少的人这样做前言:大家好,我是林克。每日分享游戏、电竞情报、攻略玩法等。从11月起,光遇又肝又氪的日子,将持续到明年2……白鹭振翅!厦门新体育中心建设进入冲刺阶段厦门新体育中心的白鹭体育场的屋面工程正在进行膜结构施工。站在环岛东路,朝东偏北方向,将目光越过宽阔的海面,能看到一个马鞍形的体育场作为国内唯一能够在场内看海的体育场,厦门……骁龙8Gen2提前进入赛道!或感到天玑9000威胁比预期大来自台湾省供应链的爆料者手机晶片达人透露,由于联发科最新的天玑9000威胁比预期大,高通在台积电投片的4nm骁龙8Gen2正在提前交付,预计明年4月就可以出片,甚至快的话等5或……因纽特人的腌海雀,臭到令人呕吐,为什么却被当地人奉为美食?文科学虫洞在寒冷的北极地区,环境十分恶劣,但是因纽特人却在这里世代生活,迄今为止至少有4000多年历史。他们居住的是球形的冰雪屋,日常吃的食物也跟我们大不一样,最为……
冬季类风湿反复发作,小心落下病根夏天治疗类风湿事半功倍,进入伏天,类风湿的患者从体感上会更加舒服一些,但是这时候也不要掉以轻心,抓住夏季扶阳治疗的好时机,帮你减少冬季发病或者不发病。中医认为,自然界存在许多致……一根电源线就能同时给多达5部电器充电,节省了桌面空间这两年手边常用的电子设备渐渐多了起来,充电都成了一件麻烦事,要想同时给多台设备充电的话,插座还真不够用,特别是到了冬天,取暖器、热水壶之类的电器也是插座上的常客,碰上手机、耳机……郑强教授年年奥林匹克竞赛,中国小孩能把外国小孩打得片甲不回我国是一个教育大国,父母对孩子的教育都十分重视,甚至把一辈子的心血都放在培养孩子成才身上,但即便如此,能够真正成为人才的人少之又少,尤其是数理化方面的人才,在世界上来说排名都非……MiniLED还是OLED?显示器的这些知识你得掌握稿源:中关村在线从液晶显示器取代CRT开始,显示器的结构开始发生翻天覆地的变化。MiniLED背光技术作为如今液晶显示器的顶流,自今年年初开始就受到了各大显示器厂商和用户……赌徒搅肉机在中国股市,炒股要看基本面吗?大A就是巨型吞金兽,一赚二平七亏的格局一直没有改变,十年过去了,经济飞速发展,大A定力十足,还是3000点。平民入市不管是投资还是投机,就象进了搅……作为当下国内最大的游戏平台,steam一直是很多玩家玩游戏的不过近期steam做了更新,部分玩家反馈进不去steam,遇到网络错误的问题,为此笔者专门给各位说一个简单不要钱的办法。在遇到打不开的情况出现的时候,基本问题都是网络问题……穆基勒对平局并不满意,球队还需要在进攻和防守方面有所提高直播吧10月9日讯法甲第10轮,巴黎客场与兰斯握手言和,双方战成0比0互交白卷。赛后,巴黎后卫穆基勒谈到了本场比赛。穆基勒说:我们把裁判的判罚搁置一边,来谈论我们本场比赛……中国经济升温预期增强人民日报海外版10月9日,中国人民银行发布2022年第三季度针对企业家、银行家和城镇储户的最新问卷调查报告。其中,企业家宏观经济热度指数为26。9,比上季度上升0。4个百……华为Mate50的这份坚持,是十年的厚积薄发,还有创新的追求建立在鸿蒙2基础上升级的鸿蒙3带来更多交互新特性,然而发布会上介绍的功能,总会觉得有一种言犹未尽之意,似乎还隐藏着更多技能点尚未公开。余承东在发布会末尾留下一个问界M5EV将在……周掌柜咨询黄仁勋元宇宙在未来非常重要说明:本文引用自澎湃新闻记者邵文文章周掌柜点评:澎湃访谈黄仁勋的这几段内容客观上并没有引发太多的注意,不过建议科技界的朋友都读几遍。首先,英伟达最近几年的进步有目共……欧冠神奇01!德甲劲旅门将把球抱进大门2进球越位,这小组乱了截至目前,欧冠首轮比赛已经打完,其中在B组,马竞21绝杀波尔图,而布鲁日则10爆冷击败勒沃库森,首轮结束后,马竞排名小组第一,而波尔图则垫底。在马竞和波尔图的比赛中,90……三星GalaxyZFlip4上市大火,Flip3处境尴尬,价三星GalaxyZFlip4常规版有四种配色可供选择,分别是经典百搭的哥特空间、甜美柔和的樱花园、高贵典雅的幽紫秘密和清爽活力的蓝海假日,可以满足不同风格的用户。如果你希望你的……
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网