優(yōu)點(diǎn):
缺點(diǎn):
實(shí)現(xiàn):
controller
@RequestMapping(value = "/start",method = RequestMethod.GET) public Mapstring,object> start(@RequestParam Mapstring, object=""> paramMap) { return testService.startQps(paramMap); }
service
@Override public Mapstring, object=""> startQps(Mapstring, object=""> paramMap) { //根據(jù)前端傳遞的qps上線 Integer times = 100; if (paramMap.containsKey("times")) { times = Integer.valueOf(paramMap.get("times").toString()); } String redisKey = "redisQps"; RedisAtomicInteger redisAtomicInteger = new RedisAtomicInteger(redisKey, redisTemplate.getConnectionFactory()); int no = redisAtomicInteger.getAndIncrement(); //設(shè)置時(shí)間固定時(shí)間窗口長(zhǎng)度 1S if (no == 0) { redisAtomicInteger.expire(1, TimeUnit.SECONDS); } //判斷是否超限 time=2 表示qps=3 if (no > times) { throw new RuntimeException("qps refuse request"); } //返回成功告知 Mapstring, object=""> map = new HashMap>(); map.put("success", "success"); return map; }
結(jié)果測(cè)試:
我們?cè)O(shè)置的qps=3 , 我們可以看到五個(gè)并發(fā)進(jìn)來后前三個(gè)正常訪問,后面兩個(gè)就失敗了。稍等一段時(shí)間我們?cè)诓l(fā)訪問,前三個(gè)又可以正常訪問。說明到了下一個(gè)時(shí)間窗口
優(yōu)點(diǎn):
缺點(diǎn):
實(shí)現(xiàn):
controller
@RequestMapping(value = "/startList",method = RequestMethod.GET) public Mapstring,object> startList(@RequestParam Mapstring, object=""> paramMap) { return testService.startList(paramMap); }
service
String redisKey = "qpsZset"; Integer times = 100; if (paramMap.containsKey("times")) { times = Integer.valueOf(paramMap.get("times").toString()); } long currentTimeMillis = System.currentTimeMillis(); long interMills = inter * 1000L; Long count = redisTemplate.opsForZSet().count(redisKey, currentTimeMillis - interMills, currentTimeMillis); if (count > times) { throw new RuntimeException("qps refuse request"); } redisTemplate.opsForZSet().add(redisKey, UUID.randomUUID().toString(), currentTimeMillis); Mapstring, object=""> map = new HashMap>(); map.put("success", "success"); return map;
結(jié)果測(cè)試:
優(yōu)點(diǎn):
缺點(diǎn):
實(shí)現(xiàn):
controller
@RequestMapping(value = "/startLoutong",method = RequestMethod.GET) public Mapstring,object> startLoutong(@RequestParam Mapstring, object=""> paramMap) { return testService.startLoutong(paramMap); }
service在service中我們通過redis的list的功能模擬出桶的效果。這里代碼是實(shí)驗(yàn)室性質(zhì)的。在真實(shí)使用中我們還需要考慮并發(fā)的問題
@Override public Mapstring, object=""> startLoutong(Mapstring, object=""> paramMap) { String redisKey = "qpsList"; Integer times = 100; if (paramMap.containsKey("times")) { times = Integer.valueOf(paramMap.get("times").toString()); } Long size = redisTemplate.opsForList().size(redisKey); if (size >= times) { throw new RuntimeException("qps refuse request"); } Long aLong = redisTemplate.opsForList().rightPush(redisKey, paramMap); if (aLong > times) { //為了防止并發(fā)場(chǎng)景。這里添加完成之后也要驗(yàn)證。 即使這樣本段代碼在高并發(fā)也有問題。此處演示作用 redisTemplate.opsForList().trim(redisKey, 0, times-1); throw new RuntimeException("qps refuse request"); } Mapstring, object=""> map = new HashMap>(); map.put("success", "success"); return map; }
下游消費(fèi)
@Component public class SchedulerTask { @Autowired RedisTemplate redisTemplate; private String redisKey="qpsList"; @Scheduled(cron="*/1 * * * * ?") private void process(){ //一次性消費(fèi)兩個(gè) System.out.println("正在消費(fèi)。。。。。。"); redisTemplate.opsForList().trim(redisKey, 2, -1); } }
測(cè)試:
public Mapstring, object=""> startLingpaitong(Mapstring, object=""> paramMap) { String redisKey = "lingpaitong"; String token = redisTemplate.opsForList().leftPop(redisKey).toString(); //正常情況需要驗(yàn)證是否合法,防止篡改 if (StringUtils.isEmpty(token)) { throw new RuntimeException("令牌桶拒絕"); } Mapstring, object=""> map = new HashMap>(); map.put("success", "success"); return map; }
@Scheduled(cron="*/1 * * * * ?") private void process(){ //一次性生產(chǎn)兩個(gè) System.out.println("正在消費(fèi)。。。。。。"); for (int i = 0; i 2; i++) { redisTemplate.opsForList().rightPush(redisKey, i); } }
以上就是詳解基于redis實(shí)現(xiàn)的四種常見的限流策略的詳細(xì)內(nèi)容,更多關(guān)于redis限流策略的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
標(biāo)簽:大慶 北京 果洛 朝陽 吉安 臺(tái)州 楊凌 江蘇
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解基于redis實(shí)現(xiàn)的四種常見的限流策略》,本文關(guān)鍵詞 詳解,基于,redis,實(shí)現(xiàn),的,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。