前言
主要針對目前線上短信被腳本惡意盜刷的情況,用Redis實現滑動窗口限流
示例代碼
public void checkCurrentWindowValue(String telNum) { String windowKey = CommonConstant.getNnSmsWindowKey(telNum); //獲取當前時間戳 long currentTime = System.currentTimeMillis(); //1小時,默認只能發5次,參數smsWindowMax做成可配置項,配置到Nacos配置中心,可以動態調整 if (RedisUtil.hasKey(windowKey)) { //參數smsWindowTime表示限制的窗口時間 //這里獲取當前時間與限制窗口時間之間的短信發送次數 Optional<Long> optional = Optional.ofNullable(RedisUtil.zCount(windowKey, currentTime - smsWindowTime, currentTime)); if (optional.isPresent()) { long count = optional.get(); if (count >= smsWindowMax) { log.error("==========>當前號碼:{} 短信發送太頻繁,{}", telNum, count); throw new ServiceException(MidRetCode.umid_10060); } } } StringBuilder sb =new StringBuilder(); String windowEle = sb.append(telNum).append(":").append(currentTime).toString(); //添加當前發送元素到zSet中(由於保證元素唯一,這里將元素加上了當前時間戳) RedisUtil.zAdd(windowKey, windowEle, currentTime); //設置2倍窗口Key:windowKey 的過期時間 RedisUtil.expire(windowKey, smsWindowTime*2, TimeUnit.MILLISECONDS); }