移除限流功能

master
toesbieya 6 years ago
parent bc2f1bbc9b
commit 5d3e2581b1
  1. 2
      java/local/src/main/java/cn/toesbieya/jxc/config/WebConfig.java
  2. 17
      java/local/src/main/java/cn/toesbieya/jxc/controller/sys/ResourceController.java
  3. 47
      java/local/src/main/java/cn/toesbieya/jxc/interceptor/RateControlInterceptor.java
  4. 15
      java/local/src/main/java/cn/toesbieya/jxc/module/request/RateLimiterHelper.java
  5. 86
      java/local/src/main/java/cn/toesbieya/jxc/module/request/RequestModule.java
  6. 10
      java/local/src/main/java/cn/toesbieya/jxc/service/sys/SysResourceService.java

@ -1,6 +1,5 @@
package cn.toesbieya.jxc.config;
import cn.toesbieya.jxc.interceptor.RateControlInterceptor;
import cn.toesbieya.jxc.interceptor.SecurityInterceptor;
import cn.toesbieya.jxc.interceptor.UserActionInterceptor;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
@ -40,7 +39,6 @@ public class WebConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) {
String[] exclude = {"/test/**", "/account/login", "/account/logout", "/account/register", "/account/checkName", "/error"};
addInterceptor(registry, new SecurityInterceptor(), exclude);
addInterceptor(registry, new RateControlInterceptor(), exclude);
addInterceptor(registry, new UserActionInterceptor(), exclude);
}

@ -1,9 +1,10 @@
package cn.toesbieya.jxc.controller.sys;
import cn.toesbieya.jxc.model.entity.SysResource;
import cn.toesbieya.jxc.service.sys.SysResourceService;
import cn.toesbieya.jxc.model.vo.Result;
import org.springframework.web.bind.annotation.*;
import cn.toesbieya.jxc.service.sys.SysResourceService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@ -17,14 +18,4 @@ public class ResourceController {
public Result getAll() {
return Result.success(service.getAll());
}
@PostMapping("update")
public Result update(@RequestBody SysResource resource) {
if (resource.getId() == null
|| resource.getTotalRate() == null
|| resource.getIpRate() == null) {
return Result.fail("参数错误");
}
return service.update(resource);
}
}

@ -1,47 +0,0 @@
package cn.toesbieya.jxc.interceptor;
import cn.toesbieya.jxc.model.vo.Result;
import cn.toesbieya.jxc.model.vo.UserVo;
import cn.toesbieya.jxc.module.request.RequestModule;
import cn.toesbieya.jxc.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
public class RateControlInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
UserVo user = SessionUtil.get(request);
if (user.isAdmin()) return true;
String url = request.getServletPath();
String ip = IpUtil.getIp(request);
int result = RequestModule.pass(url, ip);
switch (result) {
case -1:
log.warn("限流拦截,服务的总请求频率超出,url:{},用户:{},ip:{}", url, user.getName(), ip);
WebUtil.responseJson(response, Result.overload());
break;
case 0:
log.warn("限流拦截,ip已被暂时拉黑,url:{},用户:{},ip:{}", url, user.getName(), ip);
WebUtil.responseJson(response, Result.tooManyRequest());
break;
case -2:
log.warn("限流拦截,ip的请求频率超出,url:{},用户:{},ip:{}", url, user.getName(), ip);
WebUtil.responseJson(response, Result.tooManyRequest());
break;
case 1:
return true;
}
ThreadUtil.clearUser();
return false;
}
}

@ -1,15 +0,0 @@
package cn.toesbieya.jxc.module.request;
import com.google.common.util.concurrent.RateLimiter;
import lombok.Data;
@Data
public class RateLimiterHelper {
private RateLimiter limiter;
private long ipRate;
public RateLimiterHelper(long totalRate, long ipRate) {
this.limiter = RateLimiter.create(totalRate);
this.ipRate = ipRate;
}
}

@ -1,86 +0,0 @@
package cn.toesbieya.jxc.module.request;
import cn.toesbieya.jxc.model.vo.ResourceVo;
import cn.toesbieya.jxc.service.sys.SysResourceService;
import cn.toesbieya.jxc.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@Component
@Slf4j
public class RequestModule {
private final static String IP_LIMIT_KEY = "limit:url-ip:";
private final static String BLACK_IP_KEY = "limit:black-ip:";
//判断能拿到令牌的最大时间,毫秒
private final static long TIME_OUT = 200L;
//ip暂时拉黑的时间,单位秒
private final static long EXPIRE_SECONDS = 10L;
//url的总访问频率限制
private static ConcurrentHashMap<String, RateLimiterHelper> limitMap;
private SysResourceService service;
/**
* 未在resource表中配置的不进行限制
*
* @param url 请求的url
* @param ip 访问IP
* @return 0ip被暂时拉黑-1该url的服务暂时不可用-2该ip访问该url时超出规定速度1通过
*/
public static int pass(String url, String ip) {
String redisKey = url + "-" + ip;
//判断ip是否在黑名单中
if (RedisUtil.exist(BLACK_IP_KEY + redisKey)) return 0;
//判断是否超出url的总访问频率
RateLimiterHelper helper = limitMap.get(url);
if (helper == null) return 1;
if (!helper.getLimiter().tryAcquire(TIME_OUT, MILLISECONDS)) return -1;
//判断此ip是否超出url的访问频率
long count = RedisUtil.incrAndExpire(IP_LIMIT_KEY + redisKey, 1);
if (helper.getIpRate() > count - 1) return 1;
//ip暂时拉黑
RedisUtil.set(BLACK_IP_KEY + redisKey, 1, EXPIRE_SECONDS);
return -2;
}
@PostConstruct
public void init() {
Instant start = Instant.now();
initLimitMap();
Instant end = Instant.now();
log.info("路由模块启动成功,耗时:{}毫秒", ChronoUnit.MILLIS.between(start, end));
}
private void initLimitMap() {
limitMap = new ConcurrentHashMap<>();
List<ResourceVo> resources = service.getAll();
for (ResourceVo resource : resources) {
RateLimiterHelper helper = new RateLimiterHelper(resource.getTotalRate(), resource.getIpRate());
limitMap.put(resource.getUrl(), helper);
}
}
public static void updateRate(String url, long totalRate, long ipRate) {
limitMap.remove(url);
limitMap.put(url, new RateLimiterHelper(totalRate, ipRate));
}
@Autowired
public void setService(SysResourceService service) {
this.service = service;
}
}

@ -4,8 +4,6 @@ import cn.toesbieya.jxc.mapper.SysResourceMapper;
import cn.toesbieya.jxc.model.entity.SysResource;
import cn.toesbieya.jxc.model.entity.SysRole;
import cn.toesbieya.jxc.model.vo.ResourceVo;
import cn.toesbieya.jxc.model.vo.Result;
import cn.toesbieya.jxc.module.request.RequestModule;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -46,14 +44,6 @@ public class SysResourceService {
return completeNode(list);
}
public Result update(SysResource resource) {
int rows = mapper.updateById(resource);
if (rows > 0) {
RequestModule.updateRate(resource.getUrl(), resource.getTotalRate(), resource.getIpRate());
}
return Result.success("修改成功");
}
private List<ResourceVo> completeNode(List<SysResource> list) {
List<ResourceVo> result = new ArrayList<>(list.size());
HashMap<Integer, String> urlMap = new HashMap<>(128);

Loading…
Cancel
Save