You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							91 lines
						
					
					
						
							3.4 KiB
						
					
					
				
			
		
		
	
	
							91 lines
						
					
					
						
							3.4 KiB
						
					
					
				///** | 
						|
// * Copyright (C) 2018-2022 | 
						|
// * All rights reserved, Designed By www.yixiang.co | 
						|
// | 
						|
// */ | 
						|
//package co.yixiang.aspect; | 
						|
// | 
						|
//import co.yixiang.annotation.Limit; | 
						|
//import co.yixiang.exception.BadLimitRequestException; | 
						|
//import cn.iocoder.yudao.framework.common.exception.ShopException; | 
						|
//import co.yixiang.utils.RequestHolder; | 
						|
//import co.yixiang.utils.StringUtils; | 
						|
//import com.google.common.collect.ImmutableList; | 
						|
//import org.aspectj.lang.ProceedingJoinPoint; | 
						|
//import org.aspectj.lang.annotation.Around; | 
						|
//import org.aspectj.lang.annotation.Aspect; | 
						|
//import org.aspectj.lang.annotation.Pointcut; | 
						|
//import org.aspectj.lang.reflect.MethodSignature; | 
						|
//import org.slf4j.Logger; | 
						|
//import org.slf4j.LoggerFactory; | 
						|
//import org.springframework.data.redis.core.RedisTemplate; | 
						|
//import org.springframework.data.redis.core.script.DefaultRedisScript; | 
						|
//import org.springframework.data.redis.core.script.RedisScript; | 
						|
//import org.springframework.stereotype.Component; | 
						|
// | 
						|
//import javax.servlet.http.HttpServletRequest; | 
						|
//import java.lang.reflect.Method; | 
						|
// | 
						|
///** | 
						|
// * @author / | 
						|
// */ | 
						|
//@Aspect | 
						|
//@Component | 
						|
//public class LimitAspect { | 
						|
// | 
						|
//    private final RedisTemplate<Object,Object> redisTemplate; | 
						|
//    private static final Logger logger = LoggerFactory.getLogger(LimitAspect.class); | 
						|
// | 
						|
//    public LimitAspect(RedisTemplate<Object,Object> redisTemplate) { | 
						|
//        this.redisTemplate = redisTemplate; | 
						|
//    } | 
						|
// | 
						|
//    @Pointcut("@annotation(co.yixiang.annotation.Limit)") | 
						|
//    public void pointcut() { | 
						|
//    } | 
						|
// | 
						|
//    @Around("pointcut()") | 
						|
//    public Object around(ProceedingJoinPoint joinPoint) throws Throwable { | 
						|
//        HttpServletRequest request = RequestHolder.getHttpServletRequest(); | 
						|
//        MethodSignature signature = (MethodSignature) joinPoint.getSignature(); | 
						|
//        Method signatureMethod = signature.getMethod(); | 
						|
//        Limit limit = signatureMethod.getAnnotation(Limit.class); | 
						|
//        LimitType limitType = limit.limitType(); | 
						|
//        String key = limit.key(); | 
						|
//        if (StringUtils.isEmpty(key)) { | 
						|
//            if (limitType == LimitType.IP) { | 
						|
//                key = StringUtils.getIp(request); | 
						|
//            } else { | 
						|
//                key = signatureMethod.getName(); | 
						|
//            } | 
						|
//        } | 
						|
// | 
						|
//        ImmutableList<Object> keys = ImmutableList.of(StringUtils.join(limit.prefix(), "_", key, "_", request.getRequestURI().replaceAll("/","_"))); | 
						|
// | 
						|
//        String luaScript = buildLuaScript(); | 
						|
//        RedisScript<Number> redisScript = new DefaultRedisScript<>(luaScript, Number.class); | 
						|
//        Number count = redisTemplate.execute(redisScript, keys, limit.count(), limit.period()); | 
						|
//        if (null != count && count.intValue() <= limit.count()) { | 
						|
//            logger.info("第{}次访问key为 {},描述为 [{}] 的接口", count, keys, limit.name()); | 
						|
//            return joinPoint.proceed(); | 
						|
//        } else { | 
						|
//            throw new BadLimitRequestException("访问次数受限制"); | 
						|
//        } | 
						|
//    } | 
						|
// | 
						|
//    /** | 
						|
//     * 限流脚本 | 
						|
//     */ | 
						|
//    private String buildLuaScript() { | 
						|
//        return "local c" + | 
						|
//                "\nc = redis.call('get',KEYS[1])" + | 
						|
//                "\nif c and tonumber(c) > tonumber(ARGV[1]) then" + | 
						|
//                "\nreturn c;" + | 
						|
//                "\nend" + | 
						|
//                "\nc = redis.call('incr',KEYS[1])" + | 
						|
//                "\nif tonumber(c) == 1 then" + | 
						|
//                "\nredis.call('expire',KEYS[1],ARGV[2])" + | 
						|
//                "\nend" + | 
						|
//                "\nreturn c;"; | 
						|
//    } | 
						|
//}
 | 
						|
 |