限流改造

This commit is contained in:
tanghc
2019-05-21 18:49:46 +08:00
parent 8ebc0925cb
commit ae37028c61
22 changed files with 689 additions and 75 deletions

View File

@@ -16,6 +16,7 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public class DefaultLimitConfigManager implements LimitConfigManager {
public static final int LIMIT_STATUS_CLOSED = 0;
/**
* key: limitKey
*/
@@ -25,9 +26,12 @@ public class DefaultLimitConfigManager implements LimitConfigManager {
@Override
public void update(ConfigLimitDto configLimitDto) {
configLimitDto.initRateLimiter();
Long id = configLimitDto.getId();
this.remove(id);
if (configLimitDto.getLimitStatus().intValue() == LIMIT_STATUS_CLOSED) {
return;
}
configLimitDto.initRateLimiter();
Set<String> keys = this.buildKeys(configLimitDto);
idKeyMap.put(id, keys);
for (String key : keys) {

View File

@@ -25,6 +25,9 @@ import java.util.List;
* @author tanghc
*/
public class PreLimitFilter extends BaseZuulFilter {
public static final int LIMIT_STATUS_OPEN = 1;
@Override
protected FilterType getFilterType() {
return FilterType.PRE;
@@ -73,20 +76,27 @@ public class PreLimitFilter extends BaseZuulFilter {
String appKey = apiParam.fetchAppKey();
String ip = RequestUtil.getIP(request);
// 最多7种情况
String[] limitKeys = new String[]{
routeId,
appKey,
routeId + appKey,
routeId, // 根据路由ID限流
appKey, // 根据appKey限流
routeId + appKey, // 根据路由ID + appKey限流
ip + routeId,
ip + appKey,
ip + routeId + appKey,
ip, // 根据ip限流
ip + routeId, // 根据ip+路由id限流
ip + appKey, // 根据ip+appKey限流
ip + routeId + appKey, // 根据ip+路由id+appKey限流
};
List<ConfigLimitDto> limitConfigList = new ArrayList<>();
for (String limitKey : limitKeys) {
ConfigLimitDto configLimitDto = limitConfigManager.get(limitKey);
limitConfigList.add(configLimitDto);
if (configLimitDto == null) {
continue;
}
if (configLimitDto.getLimitStatus().intValue() == LIMIT_STATUS_OPEN) {
limitConfigList.add(configLimitDto);
}
}
if (limitConfigList.isEmpty()) {
return null;

View File

@@ -59,7 +59,7 @@ public @interface ApiMapping {
@AliasFor(annotation = RequestMapping.class)
RequestMethod[] method() default {RequestMethod.GET, RequestMethod.POST};
RequestMethod[] method() default {};
/**
* Alias for {@link RequestMapping#params}.

View File

@@ -3,10 +3,10 @@ package com.gitee.sop.servercommon.bean;
import com.gitee.sop.servercommon.configuration.DefaultGlobalExceptionHandler;
import com.gitee.sop.servercommon.configuration.GlobalExceptionHandler;
import com.gitee.sop.servercommon.param.ApiArgumentResolver;
import com.gitee.sop.servercommon.param.SopHandlerMethodArgumentResolver;
import com.gitee.sop.servercommon.result.DefaultServiceResultBuilder;
import com.gitee.sop.servercommon.result.ServiceResultBuilder;
import lombok.Data;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import java.util.ArrayList;
import java.util.List;
@@ -38,7 +38,7 @@ public class ServiceConfig {
/**
* 解析业务参数
*/
private HandlerMethodArgumentResolver methodArgumentResolver = new ApiArgumentResolver();
private SopHandlerMethodArgumentResolver methodArgumentResolver = new ApiArgumentResolver();
/**
* 返回结果处理

View File

@@ -1,7 +1,10 @@
package com.gitee.sop.servercommon.configuration;
import com.gitee.sop.servercommon.bean.ServiceConfig;
import com.gitee.sop.servercommon.param.SopHandlerMethodArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import java.util.List;
@@ -16,9 +19,21 @@ public class AlipayServiceConfiguration extends BaseServiceConfiguration {
ServiceConfig.getInstance().setDefaultVersion("1.0");
}
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
@Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(ServiceConfig.getInstance().getMethodArgumentResolver());
super.addArgumentResolvers(argumentResolvers);
SopHandlerMethodArgumentResolver sopHandlerMethodArgumentResolver = ServiceConfig.getInstance().getMethodArgumentResolver();
argumentResolvers.add(sopHandlerMethodArgumentResolver);
}
@Override
protected void doAfter() {
super.doAfter();
SopHandlerMethodArgumentResolver sopHandlerMethodArgumentResolver = ServiceConfig.getInstance().getMethodArgumentResolver();
List<HandlerMethodArgumentResolver> defaultArgumentResolvers = requestMappingHandlerAdapter.getArgumentResolvers();
sopHandlerMethodArgumentResolver.setResolvers(defaultArgumentResolvers);
}
}

View File

@@ -1,11 +1,9 @@
package com.gitee.sop.servercommon.param;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gitee.sop.servercommon.annotation.ApiAbility;
import com.gitee.sop.servercommon.annotation.ApiMapping;
import com.gitee.sop.servercommon.bean.ParamNames;
import lombok.Data;
import org.springframework.core.MethodParameter;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
@@ -15,17 +13,29 @@ import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 解析request参数中的业务参数绑定到方法参数上
*
* @author tanghc
*/
@Data
public class ApiArgumentResolver implements HandlerMethodArgumentResolver {
public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
private ParamValidator paramValidator = new ServiceParamValidator();
private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache =
new ConcurrentHashMap<>(256);
private final ParamValidator paramValidator = new ServiceParamValidator();
private List<HandlerMethodArgumentResolver> argumentResolvers = Collections.emptyList();
@Override
public void setResolvers(List<HandlerMethodArgumentResolver> resolvers) {
this.argumentResolvers = resolvers;
}
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
@@ -38,13 +48,22 @@ public class ApiArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
Object paramObj = this.getParamObject(methodParameter, nativeWebRequest);
// JSR-303验证
paramValidator.validateBizParam(paramObj);
return paramObj;
if (paramObj != null) {
// JSR-303验证
paramValidator.validateBizParam(paramObj);
return paramObj;
} else {
HandlerMethodArgumentResolver resolver = getOtherArgumentResolver(methodParameter);
if (resolver != null) {
return resolver.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory);
}
return null;
}
}
/**
* 获取参数对象将request中的参数绑定到实体对象中去
*
* @param methodParameter
* @param nativeWebRequest
* @return
@@ -55,17 +74,6 @@ public class ApiArgumentResolver implements HandlerMethodArgumentResolver {
Object bizObj = null;
if (bizContent != null) {
bizObj = JSON.parseObject(bizContent, parameterType);
} else {
Map<String, String[]> parameterMap = nativeWebRequest.getParameterMap();
JSONObject result = new JSONObject();
parameterMap.forEach((key, values) -> {
if (values.length > 0) {
result.put(key, values[0]);
}
});
if (result.size() > 0) {
bizObj = result.toJavaObject(parameterType);
}
}
this.bindUploadFile(bizObj, nativeWebRequest);
return bizObj;
@@ -73,7 +81,8 @@ public class ApiArgumentResolver implements HandlerMethodArgumentResolver {
/**
* 将文件绑定到
* @param bizObj 业务参数
*
* @param bizObj 业务参数
* @param nativeWebRequest
*/
protected void bindUploadFile(Object bizObj, NativeWebRequest nativeWebRequest) {
@@ -93,4 +102,21 @@ public class ApiArgumentResolver implements HandlerMethodArgumentResolver {
}
}
protected HandlerMethodArgumentResolver getOtherArgumentResolver(MethodParameter parameter) {
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
if (result == null) {
for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
if (methodArgumentResolver instanceof SopHandlerMethodArgumentResolver) {
continue;
}
if (methodArgumentResolver.supportsParameter(parameter)) {
result = methodArgumentResolver;
this.argumentResolverCache.put(parameter, result);
break;
}
}
}
return result;
}
}

View File

@@ -0,0 +1,12 @@
package com.gitee.sop.servercommon.param;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import java.util.List;
/**
* @author tanghc
*/
public interface SopHandlerMethodArgumentResolver extends HandlerMethodArgumentResolver {
void setResolvers(List<HandlerMethodArgumentResolver> resolvers);
}