Commit da3b426e authored by shenjiaqing's avatar shenjiaqing

提交代码

parent 8c9275ef
......@@ -38,7 +38,7 @@ allprojects {
}
group = "cn.com.duiba.boot"
version = "0.0.63-sjq-SNAPSHOT"
version = "0.0.73-sjq-SNAPSHOT"
}
subprojects {
......
package cn.com.duiba.spring.boot.starter.dsp.rateLimiter;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
@Activate(group = CommonConstants.CONSUMER)
public class DubboRateLimitFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
return invoker.invoke(invocation);
}
}
......@@ -11,20 +11,27 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
@Aspect
@Component
public class LimitAspect {
private static final Logger logger = LoggerFactory.getLogger(LimitAspect.class);
private final static Logger logger = LoggerFactory.getLogger(LimitAspect.class);
private final static Map<String, AtomicLong> map = new ConcurrentHashMap<>();
private final static Integer REDIS_NODE_NUM = 4;
static {
map.put("rate.limit:com.duiba.tuia.adx.web.service.algo.impl.AdxAlgoServiceImpl-hello-limit", new AtomicLong());
}
@Resource(name = "redis03StringRedisTemplate")
private StringRedisTemplate stringRedisTemplate;
......@@ -55,21 +62,27 @@ public class LimitAspect {
return joinPoint.proceed();
}
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ipAddress = getIpAddress(request);
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(ipAddress).append("-")
.append(targetClass.getName()).append("-")
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("rate.limit:").
append(targetClass.getName()).append("-")
.append(method.getName()).append("-")
.append(rateLimit.key());
logger.info("限流啦, redis key{}", stringBuffer.toString());
List<String> keys = Collections.singletonList(stringBuffer.toString());
String s = stringBuilder.toString();
long index = map.get(s).getAndIncrement() % REDIS_NODE_NUM;
Long number = stringRedisTemplate.execute(redisLuaScript, keys, String.valueOf(rateLimit.count()), String.valueOf(rateLimit.time()));
String redisKey = s + index;
logger.info("限流啦, redis key{}", redisKey);
if (number != null && number != 0 && number <= rateLimit.count()) {
List<String> keys = Collections.singletonList(redisKey);
int totalLimitCount = rateLimit.count();
int limitCount = totalLimitCount % REDIS_NODE_NUM > index ? totalLimitCount / REDIS_NODE_NUM + 1 : totalLimitCount / REDIS_NODE_NUM;
Long number = stringRedisTemplate.execute(redisLuaScript, keys, String.valueOf(limitCount), String.valueOf(rateLimit.time()));
if (number != null && number != 0 && number <= limitCount) {
logger.info("限流时间段内访问第:{} 次", number);
return joinPoint.proceed();
}
......@@ -78,31 +91,4 @@ public class LimitAspect {
throw new RuntimeException("已经到设置限流次数");
}
private static String getIpAddress(HttpServletRequest request) {
String ipAddress;
try {
ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
// = 15
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
} catch (Exception e) {
ipAddress = "";
}
return ipAddress;
}
}
dubboRateLimitFilter=cn.com.duiba.spring.boot.starter.dsp.rateLimiter.DubboRateLimitFilter
\ No newline at end of file
local key = "rate.limit:" .. KEYS[1] --限流KEY
local limit = tonumber(ARGV[1]) --限流大小
local current = tonumber(redis.call('get', key) or "0")
local current = tonumber(redis.call('get', KEYS[1]) or "0")
if current + 1 > limit then --如果超出限流大小
return 0
else --请求数+1,并设置2秒过期
redis.call("INCRBY", key,"1")
redis.call("expire", key,"2")
redis.call("INCRBY", KEYS[1], "1")
redis.call("expire", KEYS[1], "2")
return current + 1
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment