Commit cbadd4c5 by 袁伟铭

1.0.0

parent 1442e125
...@@ -30,22 +30,46 @@ import java.lang.annotation.Target; ...@@ -30,22 +30,46 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Limit { public @interface Limit {
// 限制类型 /**
* 限流类型
*
* @return
*/
LimitType limitType() default LimitType.IP; LimitType limitType() default LimitType.IP;
// 资源名称,用于描述接口功能 /**
* 资源名称,用于描述接口功能, 不设置将默认为调用方法名
*
* @return
*/
String name() default ""; String name() default "";
// 资源 key /**
* 缓存key, 不设置将默认为调用方法名
*
* @return
*/
String key() default ""; String key() default "";
// key prefix /**
* 前缀前面还会有一个{@code BaseCacheKeys.PREFIX}的项目前缀, 默认为"rate-limit"
*
* @return
*/
String prefix() default ""; String prefix() default "";
// 时间的,单位秒 /**
* 时间范围,单位秒, 在这个时间范围内可以调用多少次
*
* @return
*/
int period() default 1; int period() default 1;
// 限制访问次数 /**
* 限制访问次数
*
* @return
*/
int count() default 3; int count() default 3;
/** /**
......
...@@ -67,10 +67,13 @@ public class LimitAspect { ...@@ -67,10 +67,13 @@ public class LimitAspect {
Method signatureMethod = signature.getMethod(); Method signatureMethod = signature.getMethod();
Limit limit = signatureMethod.getAnnotation(Limit.class); Limit limit = signatureMethod.getAnnotation(Limit.class);
String key = buildLimitKey(limit, joinPoint, signatureMethod); String limitKey = buildLimitKey(limit, joinPoint, signatureMethod);
log.debug("限流缓存KEY: {}", key); log.debug(">> 限流缓存KEY: {}", limitKey);
if (limitKey == null || limitKey.trim().length() == 0) {
return;
}
List<String> keys = Collections.singletonList(key); List<String> keys = Collections.singletonList(limitKey);
String luaScript = buildLuaScript(); String luaScript = buildLuaScript();
RedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript, Long.class); RedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript, Long.class);
Long count = stringRedisTemplate.execute(redisScript, keys, String.valueOf(limit.count()), String.valueOf(limit.period())); Long count = stringRedisTemplate.execute(redisScript, keys, String.valueOf(limit.count()), String.valueOf(limit.period()));
...@@ -79,7 +82,7 @@ public class LimitAspect { ...@@ -79,7 +82,7 @@ public class LimitAspect {
String name = limit.name(); String name = limit.name();
name = StringUtils.isNotBlank(name) ? name : signatureMethod.getName(); name = StringUtils.isNotBlank(name) ? name : signatureMethod.getName();
logger.info("第{}次访问key为 {},描述为 [{}] 的接口", count, keys, name); logger.debug("第{}次访问,KEY为 {},描述为 [{}] 的接口", count, keys, name);
} }
/** /**
...@@ -146,7 +149,11 @@ public class LimitAspect { ...@@ -146,7 +149,11 @@ public class LimitAspect {
log.warn(">> 未找到对象,限流失败: {}", joinPoint); log.warn(">> 未找到对象,限流失败: {}", joinPoint);
break; break;
} }
String fieldValue = getPojoField(field, args[0]); String fieldValue = getPojoField(args[0], field);
if (StringUtils.isBlank(fieldValue)) {
log.warn(">> 对象字段值为空,请检查限流字段是否准确,限流失败: {}", joinPoint);
break;
}
limitKey = BaseCacheKeys.rateLimitKey(LimitType.POJO_FIELD, prefix, key, fieldValue); limitKey = BaseCacheKeys.rateLimitKey(LimitType.POJO_FIELD, prefix, key, fieldValue);
break; break;
case PARAM: case PARAM:
...@@ -174,7 +181,7 @@ public class LimitAspect { ...@@ -174,7 +181,7 @@ public class LimitAspect {
|| (param instanceof Byte); || (param instanceof Byte);
} }
private String getPojoField(String field, Object pojo) { private String getPojoField(Object pojo, String field) {
try { try {
JSONObject object = JSON.parseObject(JSON.toJSONString(pojo)); JSONObject object = JSON.parseObject(JSON.toJSONString(pojo));
return object.getString(field); return object.getString(field);
......
...@@ -2,6 +2,7 @@ package com.zq.user.controller.app; ...@@ -2,6 +2,7 @@ package com.zq.user.controller.app;
import com.zq.common.annotation.Limit; import com.zq.common.annotation.Limit;
import com.zq.common.config.limit.LimitType;
import com.zq.common.utils.AssertUtils; import com.zq.common.utils.AssertUtils;
import com.zq.common.utils.ValidateUtil; import com.zq.common.utils.ValidateUtil;
import com.zq.common.vo.ApiTokenVo; import com.zq.common.vo.ApiTokenVo;
...@@ -25,6 +26,8 @@ public class UserController { ...@@ -25,6 +26,8 @@ public class UserController {
private final UserService userService; private final UserService userService;
// 30秒只能访问一次
@Limit(limitType = LimitType.PARAM, keyParamIndex = 0, period = 30, count = 1, name = "发送验证码", errMsg = "请稍后再试!")
@ApiOperation("发送验证码") @ApiOperation("发送验证码")
@GetMapping(value = "/sendCode") @GetMapping(value = "/sendCode")
public ResultVo sendCode(String phone) { public ResultVo sendCode(String phone) {
...@@ -71,7 +74,6 @@ public class UserController { ...@@ -71,7 +74,6 @@ public class UserController {
return ResultVo.success(userService.passwdLogin(vo)); return ResultVo.success(userService.passwdLogin(vo));
} }
@Limit(count = 1)
@ApiOperation("获取用户信息") @ApiOperation("获取用户信息")
@GetMapping(value = "/getUserInfo") @GetMapping(value = "/getUserInfo")
public ResultVo getUserInfo(@RequestParam String userId) { public ResultVo getUserInfo(@RequestParam String userId) {
......
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